I'm not too clear on the terminology, so excuse the title.
What I'm looking for is the answer on how to do this:
This is the map:
Map<String, Map<String, String>> theMap = new HashMap<String, Map<String, String>>();
And this is the way I'm trying to add to it, I hope it provides enough insight:
theMap.put("string", {"a"="b"});
(that doesn't work)
If you want to add a Map<String, String> to a Map<String, Map<String, String>> the code below is the way to go:
Map<String, Map<String, String>> theMap = new HashMap<String, Map<String, String>>();
Map<String, String> innerMap = new HashMap<String, String>();
innerMap.put("a", "b");
theMap.put("string", innerMap);
We create a variable innerMap of type Map<String, String> and simply add it to the theMap object.
You need to add subMap to theMap object :
Map<String, Map<String, String>> theMap = new HashMap<>();
Map<String, String> subMap = new HashMap<>();
subMap.put("a","b");
theMap.put("string",subMap);
The value is Map<String, String>, not String. You need to add new Map and insert the values to this Map
theMap.put("string", new LinkedHashMap<String, String>() {{
put("a","b");
}});
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
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);
HashMap<String, String> foo = new HashMap<String, String>();
HashMap<String, String> baar = new HashMap<String, String>();
How to remove items found in baar from foo?
You can try:
foo.keySet().removeAll(baar.keySet())
Changes to a Map's keySet() are reflected in the map itself.
If you want to remove exact mappings (not just based on keys), you can use the same approach with the entrySet() instead:
foo.entrySet().removeAll(baar.entrySet());
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);