Jaspreet Jolly
Jaspreet Jolly

Reputation: 1313

Combining remove and put method in LinkedHashMap

With a LinkedHashMap, when I try to reinsert same key with different value, it replaces the value and maintains the order of key i.e if I do this

Map<String,String> map = new LinkedHashMap<>();
map.put("a", "a");
map.put("b", "b");
map.put("c", "c");
map.put("d", "d");
map.values().stream().forEach(System.out::print);    

Output: abcd

Now if I add in the map a different value with same key,the order remains the same i.e

map.put("b", "j");
map.values().stream().forEach(System.out::print); 

Output: ajcd

Is there any other way? One is to remove and reinsert key with new value, which prints acdj as output. In my case I want to do it for multiple keys based on some property of object used as value?

Solution using streams would be preferable.

Upvotes: 3

Views: 1896

Answers (3)

AxelH
AxelH

Reputation: 14572

This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order). Note that insertion order is not affected if a key is re-inserted into the map

LinkedHashMap javadoc.

it keep track of the keys insertion, and if we add the Map.put javadoc :

If the map previously contained a mapping for the key, the old value is replaced by the specified value.

Map javadoc

The Entry is not replace, only the value is modified so the key remains the same.

You need to remove and then insert the value to update the ordering of the keys.

Upvotes: 2

TreffnonX
TreffnonX

Reputation: 2930

A HashMap is not sorted by either keys or values. What you are looking for is a TreeMap. For a HashMap, the only guarantee is, that the keys are hashed and put in an array, based on their hash.

The LinkedHashMap, according to the Javadoc, creates an internal LinkedList, and tracks the original insertion order of entries. In other words, if you use LinkedHashMap, you won't, necessariely receive a 'sorted' list at all.

You have two options to work around this: Either use a TreeMap (or derivate thereof), or sort every time, you want to output the values. TreeMaps have an internal sorting, based on their keys. If the keys are compared to each other the way you'd expect (by comparing the Strings) then you get a properly ascending sorting, based on the keys. However this does not solve your problem, that you want to sort the values.

To solve your original problem, use a bidirectional TreeMap. Apache Commons4 implements such a map (https://commons.apache.org/proper/commons-collections/javadocs/api-4.3/org/apache/commons/collections4/bidimap/AbstractDualBidiMap.html#values--) It allows you to access both a key and a value set. But be aware that this map will not work for you, if your values are not unique. Like keys, all values in a bidirectional map need to be unique, because they need to serve as keys themselves.

From the Javadoc:

This map enforces the restriction that there is a 1:1 relation between keys and values, meaning that multiple keys cannot map to the same value. This is required so that "inverting" the map results in a map without duplicate keys. See the put(K, V) method description for more information.

Upvotes: 0

Surya Bharathi
Surya Bharathi

Reputation: 9

Hashmap insertion is based on hashcode only. For example a key of "b" has a hashcode as 98.

for map.put("b", "b");

you inserting as a key "b" which has hascode 98. so it will look like. 98 ---> holds value 'b'.

again if you try to put on same key "b" which has a hashcode 98 only. so hashmap try to link on same hashcode only which is 98 ---> holds "j" as a value.

for know working of hashmap hashcode check out below link https://www.geeksforgeeks.org/internal-working-of-hashmap-java/

Upvotes: -2

Related Questions