HashMap to TreeMap - java

I am using TreeMap to sort the keys in the Map.
Map<Byte, List<TagEntity>> hashMap = list.stream().collect(Collectors.groupingBy(TagEntity::getTagType));
Map<Byte, List<TagEntity>> treeMap = new TreeMap<>(Comparator.reverseOrder());
But how to convert HashMap to TreeMap?

You can create the TreeMap directly by passing a map supplier to groupingBy:
Map<Byte, List<TagEntity>> treeMap =
list.stream()
.collect(Collectors.groupingBy(TagEntity::getTagType,
() -> new TreeMap<Byte, List<TagEntity>>(Comparator.reverseOrder()),
Collectors.toList()));

This is how you can create hashmap to treemap:
HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
TreeMap<Integer, String> treeMap = new TreeMap<Integer, String>();
treeMap.putAll(hashMap);
Refer here java-putting-hashmap-into-treemap

This should work:
TreeMap treeMap = new TreeMap<>(hashMap);
Or:
treeMap.putAll(hashMap);

Related

Best way to find element in List Java [duplicate]

It's a simple question,
I have a simple HashMap of which i want to reverse the keys and values.
HashMap<Character, String> myHashMap = new HashMap<Character, String>();
myHashMap.put('a', "test one");
myHashMap.put('b', "test two");
and I want to create a new HashMap in which i put the opposites.
HashMap<String, Character> reversedHashMap = new HashMap<String, Character>();
e.g. Keys "test one" & "test two" and values 'a' & 'b'.
They all are unique, yes
If you're sure that your values are unique you can iterate over the entries of your old map .
Map<String, Character> myNewHashMap = new HashMap<>();
for(Map.Entry<Character, String> entry : myHashMap.entrySet()){
myNewHashMap.put(entry.getValue(), entry.getKey());
}
Alternatively, you can use a Bi-Directional map like Guava provides and use the inverse() method :
BiMap<Character, String> myBiMap = HashBiMap.create();
myBiMap.put('a', "test one");
myBiMap.put('b', "test two");
BiMap<String, Character> myBiMapInversed = myBiMap.inverse();
As java-8 is out, you can also do it this way :
Map<String, Integer> map = new HashMap<>();
map.put("a",1);
map.put("b",2);
Map<Integer, String> mapInversed =
map.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey))
Finally, I added my contribution to the proton pack library, which contains utility methods for the Stream API. With that you could do it like this:
Map<Character, String> mapInversed = MapStream.of(map).inverseMapping().collect();
Apache commons collections library provides a utility method for inversing the map. You can use this if you are sure that the values of myHashMap are unique
org.apache.commons.collections.MapUtils.invertMap(java.util.Map map)
Sample code
HashMap<String, Character> reversedHashMap = MapUtils.invertMap(myHashMap)
If the values are not unique, the safe way to inverse the map is by using java 8's groupingBy function
Map<String, Integer> map = new HashMap<>();
map.put("a",1);
map.put("b",2);
Map<Integer, List<String>> mapInversed =
map.entrySet()
.stream()
.collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())))
I wrote a simpler loop that works too (note that all my values are unique):
HashMap<Character, String> myHashMap = new HashMap<Character, String>();
HashMap<String, Character> reversedHashMap = new HashMap<String, Character>();
for (char i : myHashMap.keySet()) {
reversedHashMap.put(myHashMap.get(i), i);
}
To answer your question on how you can do it, you could get the entrySet from your map and then just put into the new map by using getValue as key and getKey as value.
But remember that keys in a Map are unique, which means if you have one value with two different key in your original map, only the second key (in iteration order) will be kep as value in the new map.
Iterate through the list of keys and values, then add them.
HashMap<String, Character> reversedHashMap = new HashMap<String, Character>();
for (String key : myHashMap.keySet()){
reversedHashMap.put(myHashMap.get(key), key);
}
private <A, B> Map<B, A> invertMap(Map<A, B> map) {
Map<B, A> reverseMap = new HashMap<>();
for (Map.Entry<A, B> entry : map.entrySet()) {
reverseMap.put(entry.getValue(), entry.getKey());
}
return reverseMap;
}
It's important to remember that put replaces the value when called with the same key. So if you map has two keys with the same value only one of them will exist in the inverted map.
Tested with below sample snippet, tried with MapUtils, and Java8 Stream feature. It worked with both cases.
public static void main(String[] args) {
Map<String, String> test = new HashMap<String, String>();
test.put("a", "1");
test.put("d", "1");
test.put("b", "2");
test.put("c", "3");
test.put("d", "4");
test.put("d", "41");
System.out.println(test);
Map<String, String> test1 = MapUtils.invertMap(test);
System.out.println(test1);
Map<String, String> mapInversed =
test.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
System.out.println(mapInversed);
}
Output:
{a=1, b=2, c=3, d=41}
{1=a, 2=b, 3=c, 41=d}
{1=a, 2=b, 3=c, 41=d}
Use forEach introduced in Java 8
Map<Short, String> regularMap = new HashMap<>();
Map<String, Short> inversedMap = new HashMap<>();
regularMap.forEach((key, value) -> inversedMap.put(value, key));
for reverting the map, in your case:
private void reverseMap(Map<Character, String> map) {
Map<String, Character> newList = new HashMap<>();
map.forEach((key, value) -> newList.put(value, key));
System.out.println(newList);
}
or you can traverse the old hashmap
HashMap<String, Character> newList = new HashMap<String, Character>();
for (String key : list.keySet()){
newList.put(list.get(key), key);
}
For Reversing the Array of Dictionary. (If values are Unique)
private void reverseArrayMap(List<Map<String, String>> list) {
// reversing the array of dictionary
List<Map<String, String>> newList = new ArrayList<>();
Map<String, String> resDic = new HashMap<>();
for (Map<String, String> map : list) {
map.forEach((key, value) -> resDic.put(value, key));
newList.add(resDic);
}
System.out.println("Original Array of Dictionary" + list);
System.out.println("Reversed Array of Dictionary" + newList);
}
Java :
Simple approach, No need for java 8
Map<String,String> map=new HashMap<>();
Map<String,String> mapInv=new HashMap<>();
for (String key : map.keySet())
mapInv.put(map.get(key), key);
Java 8:
forEach() is a new method to iterate the elements. It is defined in Iterable and Stream interface.
Map<String,String> map=new HashMap<>();
Map<String,String> mapInv=new HashMap<>();
map.forEach((key, value) -> mapInv.put(value, key));
Kotlin :
val map: Map<String, String> = HashMap()
val mapInv: MutableMap<String?, String> = HashMap()
for (key in map.keys) mapInv[map[key]] = key

how to make Hashmap orderly?

can I get a Hashmap which key orderly except use LinkeHashmap?
Map<String,String> myMapTmp = XXDao().getXXX();
Map<String,String> myMap = new LinkedHashMap<String,String>();
List<String> keyList = new ArrayList<String>();
Iterator<String> it =myMapTmp.keySet().iterator();
while(it.hasNext()){
keyList.add(it.next());
}
Collections.sort(keyList);
Iterator<String> it2 = keyList.iterator();
while(it2.hasNext()){
String key = it2.next();
myMap.put(key, myMapTmp.get(key));
}
You can use TreeMap with mappings of HashMap
Map<String,String> myMapTmp = XXDao().getXXX();
// TreeMap keeps all entries in sorted order
TreeMap<String, String> sortedMap = new TreeMap<>(myMapTmp);
Set<Entry<String, String>> mappings = sortedMap.entrySet();
System.out.println("HashMap after sorting by keys in ascending order ");
for(Entry<String, String> mapping : mappings){
System.out.println(mapping.getKey() + " ==> " + mapping.getValue());
}
You can create a treeMap from the existing map so the treeMap will have all the entries sorted.
TreeMap<Integer, String> treeMap = new TreeMap<Integer, String>();
treeMap.putAll(myMapTmp);
Simply use LinkedHashMap. it will give you desired result.

Join two maps by key

I have two maps:
Map<Integer, String> mapOne = {(1,"a"), (2, "b")};
Map<Integer, Double> mapTwo = {(1,10.0), (2,20.0)};
and I want to combine this maps into one by Integer value, so the result map is
Map<String, Double> mapResult = {("a",10.0), ("b",20.0)};
Is there any way to do this easier than iterate over entry set?
Assuming that the keys of the two maps match and that the maps have the same number of entries, with Java 8 you can write it in one line with:
Map<String, Double> map = mapOne.entrySet().stream()
.collect(toMap(e -> e.getValue(),
e -> mapTwo.get(e.getKey())));
So you start from the first map and create a new map where the keys are the values of mapOne and the values are the corresponding values in mapTwo.
Technically this is somewhat equivalent to iterating over the entry set of the first map though.
Note: requires import static java.util.stream.Collectors.toMap;
Looks like only iteration:
#Test
public void testCollection() {
Map<Integer, String> mapOne = new HashMap<Integer, String>();
mapOne.put(1, "a");
mapOne.put(2, "b");
Map<Integer, Double> mapTwo = new HashMap<Integer, Double>();
mapTwo.put(1, 10.0);
mapTwo.put(2, 20.0);
Map<String, Double> mapResult = new HashMap<String, Double>();
Set<Integer> keySet = mapOne.keySet();
keySet.retainAll(mapTwo.keySet());
for (Integer value : keySet) {
mapResult.put(mapOne.get(value), mapTwo.get(value));
}
System.out.println(mapResult);
}
If the maps were the same type, you could use a putAll(), but since you are changing the key value pairs, it looks like you are going to have to iterate over each integer, get() from each map, then put(mapOneVal,mapTwoVal)
for(int i=0;i<max;i++){
String key = mapOne.get(i);
Double val = maptwo.get(i);
if(key!=null && val!=null)
map3.put(key,val);
}

how to add Map contents to Multimap?

Map<String,String> map1= new HashMap<String, String>(){{
put("no1","123"); put("no2","5434"); put("no5","234");}};
Map<String,String> map2 = new HashMap<String, String>(){{
put("no1","523"); put("no2","234"); put("no3","234");}};
Multimap<String, String> totalMap = ArrayListMultimap.create();
totalMap.putAll() supports only Multimap. How Can I put all map1 and map2 to the multimap ?
Use Multimaps.forMap(Map<K,V>) to get a Multimap view of your map, then add that to the totalMap, e.g.:
totalMap.putAll(Multimaps.forMap(map1));

copying a java treemap of treemap using putAll()

I have a TreeMap within a TreeMap.
TreeMap <String, TreeMap<String, Double>> x_probs_org = new TreeMap<String, TreeMap<String, Double>>();
But when I make another one with exactly the same definition, and then copy the first one:
x_probs.putAll(x_probs_org);
I notice the new treemap doesn't copy everything. It copies all the String keys correctly, but only the last element in the value (TreeMap). Is there any easier way to do this right, apart from scrolling through the entire first treemap and then adding the elements to the new one?
I just need to have identical data structures with identical data to begin with. What I did was to run the loop through which I populated the first treemap, and then simply put the next one with it, in the same loop. This didn't work either:
// build tempMap up there...
x_probs_org.put(tokens[0], tempMap);
x_probs.put(tokens[0], tempMap);
x_probs insists on missing data that x_probs_org manages to get. Does "tempMap" get exhausted by populating something once?
This works for me:
public static void main(String[] args) {
Map <String, Map<String, Double>> map = new TreeMap<String, Map<String, Double>>();
Map<String, Double> innerMap = new TreeMap<String, Double>();
innerMap.put("a", 1.0);
innerMap.put("b", 2.0);
map.put("inner1", innerMap);
innerMap = new TreeMap<String, Double>();
innerMap.put("c", 3.0);
innerMap.put("d", 4.0);
map.put("inner2", innerMap);
Map <String, Map<String, Double>> newMap = new TreeMap<String, Map<String, Double>>();
newMap.putAll(map);
System.out.println(map); // prints {inner1={a=1.0, b=2.0}, inner2={c=3.0, d=4.0}}
System.out.println(newMap); // prints {inner1={a=1.0, b=2.0}, inner2={c=3.0, d=4.0}}
}
Another Easy Way as following:
newMap = x_probs_org.clone();
You can simply use the TreeMap(SortedMap<K,? extends V> m) constructor, like this:
TreeMap <String, TreeMap<String, Double>> x_probs_org = new TreeMap<String, TreeMap<String, Double>>();
TreeMap <String, TreeMap<String, Double>> x_probs = new TreeMap<String, TreeMap<String, Double>>(x_probs_org);
Most likely you are reusing references (like tempMap) and that's why also your x_probs_org is not what you expect it to be. Or you get surprised because you modify elements of copy via original.
Following works perfectly:
TreeMap<String, TreeMap<String, Double>> x_probs_org =
new TreeMap<String, TreeMap<String, Double>>();
TreeMap<String, Double> inner = new TreeMap<String, Double>();
inner.put("entry1", 1d);
inner.put("entry2", 2d);
x_probs_org.put("inner", inner);
TreeMap<String, TreeMap<String, Double>> x_probs =
new TreeMap<String, TreeMap<String, Double>>();
x_probs.putAll(x_probs_org);

Categories