How to get the overridden keys value in HashMap - java

Map<String,String> mapp=new HashMap<>();
mapp.put("1", "abc");
mapp.put("1", "def");
System.out.println(mapp.size());
System.out.println(mapp.get("1"));
System.out.println(mapp);
o/p
1
def
{1=def}
How to get 'abc' value and wheather its present in the map as size is 1.
Can this be a case of hash collision, as the key is same can it produce same hashcode and store in the same index?

mapp.put("1", "def"); would return the previous value - "abc" - of the key "1".
You can see it with:
System.out.println(mapp.put("1", "def"));
Afterwards, there's no way to obtain the original value of the "1" key, since it has been overwritten.
This is specified in the Javadoc of put:
V java.util.Map.put(K key, V value)
Associates the specified value with the specified key in this map (optional operation). If the map previously contained a mapping for the key, the old value is replaced by the specified value. (A map m is said to contain a mapping for a key k if and only if m.containsKey(k) would return true.)
Returns:
the previous value associated with key, or null if there was no mapping for key.

Once you have clobbered a key's value in a hashmap, that value is for all intents and purposes gone. If you have a need to keep track of multiple values associated with a key, then consider using a map of some sort of collection:
Use a map of lists:
Map<String, List<String>> mapp = new HashMap<>();
List<String> list = new ArrayList<>();
list.add("abc");
list.add("def");
mapp.put("1", list);

Related

What is this Java method doing?

public Map mystery(Map map1, Map map2) {
Map result = new TreeMap();
for (String s1 : map1.keySet()) {
if (map2.containsKey(map1.get(s1))) {
result.put(s1, map2.get(map1.get(s1)));
}
}
return result;
}
map1={bar=1, baz=2, foo=3, mumble=4}; map2={1=earth, 2=wind, 3=air, 4=fire}
For each key in map1 method looks at the corresponding value and of this value exists as a key in map2 than puts it a new TreeMap.
Consider one iteration. map1 has key bar and it's value is 1. Now map2 has 1 as it's key with value earth. So data that is put in new Map is bar:earth and so on..
Also note since resultant map is a TreeMap elements will be stored in Lexicographical order (Since keys are Strings and TreeMap stores elements in sorted order as per keys natural ordering).
It's calculating the composition of the functions map2(map1), along with giving you an impressive number of raw-type warnings.

Looping Hash Map does not return correct Key

I have a hash map type array list:
public static ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
It has some IDs and Names like this:
This is the code that is used to loop through:
for (HashMap<String, String> map : mylist)
for (Entry<String, String> entry : map.entrySet())
if(entry.getValue().contains(typedText)){
map1 = new HashMap<String, String>();
map1.put("id", entry.getKey());
map1.put("name", entry.getValue());
mylist1.add(map1);
}
Problem is that in this line:
for (Entry<String, String> entry : map.entrySet())
map.entrySet() shows correct ID and the Name like this:
But only Name is available with 'entry':
entry.getKey() always returns the text 'name' which is the key and entry.getValue() returns 'Katie Bailey' which is the value.
My question is why am I not getting the key with entry.getKey()? Why do I always get 'name' as the key with each iteration?
I suspect you're getting confused by the debugger's visualization of the map. When it's showing this:
{id=2990511, name=Katie Bailey}
that's showing that your map has two entries - one with a key of id and a value of "2990511", and one with a key of name and a value of "Katie Bailey".
You're then looping over all those entries, and if the value matches you're adding two entries into a second map: one entry with the key id and a value which is the key of the entry you're looking at, and a second entry with the key name and a value which is the value of the entry you're looking at. You're not using the whole of the original map - you're just using that single entry.
So if you match on the entry of name=Katie Bailey you end up with a new map containing two entries:
{id=name, name=Katie Bailey}
It's not really clear what you were expecting, but the results you've shown make perfect sense with your code.
I suspect you actually want something like:
for (HashMap<String, String> map : mylist) {
String name = map.get("name");
if (name.contains(typedText)) {
// Create a copy of the whole map
mylist1.add(new HashMap<String, String>(map));
}
}
If you've got fixed keys though, you should at least consider creating a type to encapsulate the data - e.g. a Person class with getName() and getId() methods.
The issue is map only takes unique values for the key, therefore, if a key exists in the map, it cannot be re-inserted in the map, that results in you getting the first matching value.
For that matter you have to provide different keys to be substituted. Using a string such as "id" or "name" for the key means that key does not change, and so does the value.
Refer to Java HashMap API

How to print all the values for a key in HashMap in java

Map<String, String> map = new HashMap<String, String>();
map.put("1", "xyz");
map.put("1", "abc");
map.put("1", "cde");
map.put("2", "err");`
`
for the above map I want to get all the values associated with the key 1. Expected output.
Key:: 1 values are:: xyz, abc, cde
Order of the values doesn't important.
In a Map the key should always be unique. If you associate a new value to an existing key, it will overwrite the value of the existing entry.
You might need to check the interface for Map#put(K, V) method.
If the map previously contained a mapping for the key, the old value
is replaced by the specified value.
So in your case your map will always have "cde" as the value for the key "1".
Use MultiMap
MultiMap mapValue = new MultiValueMap();
mapValue.put("1", "xyz");
mapValue.put("1", "abc");
mapValue.put("1", "cde");
mapValue.put("2", "err");
System.out.println("Map : " + mapValue);
Output: Map : {2=[err], 1=[xyz, abc, cde]}
A map can not have duplicate keys.
If you want to implement what you describe in question. First you need to use multimaps
What you are doing is wrong.
Map doesn't allow duplicates.
So one key -----------> one value
If you see docs of put()
Associates the specified value with the specified key in this map (optional operation). If the map previously contained a mapping for the key, the old value is replaced by the specified value. (A map m is said to contain a mapping for a key k if and only if m.containsKey(k) would return true.)
You can print the values of each key and value like
Ex:
Map<String, String> map = new HashMap<String, String>();
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
In Map you can't have duplicate keys. so In your case final value put for key 1. "cde" will remain in Map
You can do some thing like following to achive what you are expecting
Map<String, List<String>> map = new HashMap<>();
List<String> list=new ArrayList<>();
List<String> list1=new ArrayList<>();
list.add("xyz");
list.add("abc");
list.add("cde");
list1.add("err");
map.put("1", list);
map.put("2",list1);
System.out.println(map.get("1"));
HashMap::put overrides the old value associated with the key. You have to put a List in each map entry and insert new values in the appropriate list.
From the java documentation about HashMap.put(K key, V value) method:
Associates the specified value with the specified key in this map. If the map previously contained a mapping for the key, the old value is replaced.
So you can't do that.
This is impossible, a map is called a map because it maps one key value to a value. Multiple keys can map to the same value but not the other way around.
What you probably want is a map which maps to a List<String> instead:
final Map<String, List<String>> map = new HashMap<>();
if (map.get("1") == null) {
map.put("1", new ArrayList<String>());
}
map.get("1").add("xyz");
// ...
A helper function for adding might be convenient
public static <K, V> void add(final K key, final V value, final Map<K, List<V>> map)
{
if (map.get(key) == null) {
map.put(key, new ArrayList<V>());
}
map.get(key).add(value);
}
You can not do this with this type of Map. The key in map must be unique.
To be able to do that you should declare a map, where key is string but values are collections of Strings.
Map<String,Collection<String>> map = new HashMap<String,Collection<String>>();
The to list values from it you can do this
for(String valueOfKey : map.get("key") {
//print or something else
}
Note that to add some values to it you must first check that key is already stored and if not then fist declare a collection.
if(map.contains("key") == false) {
map.put(new ArrayList<String>());
}
map.get("key").add("value");
As this is well know design you might be interest in guava framework and Multimap
The benefit of this class is that it already has implemented the logic how to add and retrieve values from it.
You could do something like:
for (String k : map.keySet())
System.out.println(k);
This would print the keys in the HashMap, but without any guarantees on order.
You can not have duplicate key for a hash map see the below S.O for What happens for duplicate keys in HashMap

extract an element from an hash map and update it

If I extract an element from a hash map through the method get(<key>) and update the extracted element, will these updates persist in the map? Or do I have to re-insert the element back to the hash map?
If you change fields of the object you got out, like this...
Thing thing = map.get(key);
thing.setOtherThing(yetAnotherThing);
then that'll update the value in the map.
On the other hand, if you modify the reference that you obtained by getting a value out of the map...
Thing thing = map.get(key);
thing = doSomethingWith(thing);
then you need to put it back into the map.
If you modify the object obtained by the Map.get(K) method, the object does not need to be re-inserted. However, if you change a key in a way that the hashCode() function is affected, then you need to remove the map entry before modifying the key and then you can put back your value using your new key.
Consider the following map corruption case:
Map<List<String>, String> map = new HashMap<List<String>, String>();
List<String> key1 = new ArrayList<String>();
key1.add("key1");
map.put(key1, "value1");
System.out.println(map.get(key1)); //prints "value1"
key1.add("buzz2");
System.out.println(map.get(key1)); //prints "null"
List<String> k = map.keySet().iterator().next();
System.out.println(map.get(k)); //prints "null"
Morale of the story: for maps, always use immutable keys like String or int.

How to retrieve all the values associated with a key?

I want to get all the values associated with a key in Map.
For e.g,
Map tempMap = new HashMap();
tempMap.put("1","X");
tempMap.put("2","Y");
tempMap.put("3","Z");
tempMap.put("1","ABC");
tempMap.put("2","RR");
tempMap.put("1","RT");
How to retrieve all the values associated with key 1 ?
the thing you must understand is that in a Map, the key is unique.
that means that after
tempMap.put("1","X");
"1" is mapped to "X"
and after
tempMap.put("1","ABC");
"1" is mapped to "ABC" and the previous value ("X") is lost
From the HashMap javadoc:
public V put(K key, V value)
Associates the specified value with the specified key in this map. If the map previously contained a mapping for the key, the old value is replaced.
What you can do is this:
Map<String, List<String>> tempMap = new HashMap<String, List<String>>();
tempMap.put("1", new LinkedList<String>());
tempMap.get("1").add("X");
tempMap.get("1").add("Y");
tempMap.get("1").add("Z");
for(String value : tempMap.get("1")) {
//do something
}
This compartmentalizes values that correspond to the key "1" into their own list, which you can easily access. Just don't forget to initialize the list... else NullPointerExceptions will come to get you.
Yuval =8-)
can't
try using google collections's Multimap
I think you're missing something important:
Map tempMap = new HashMap();
tempMap.put("1","X");
tempMap.put("2","Y");
tempMap.put("3","Z");
tempMap.put("1","ABC"); // replaces "X"
tempMap.put("2","RR"); // replaces "Y"
tempMap.put("1","RT"); // replaces "ABC"
Also, you should use generics where possible, so your first line should be:
Map<String, String> tempMap = new HashMap<String, String>();
To do that you have to associate each key with a Set of values, with corresponding logic to create the set and enter/remove values from it instead of simple put() and get() on the Map.
Or you can use one of the readymade Multimap implementations such as the one in Apache commons.

Categories