Why is map.put not maintaining the ordering of keys [duplicate] - java

This question already has answers here:
Java Class that implements Map and keeps insertion order?
(8 answers)
Closed 8 years ago.
I have defined a dictionary :
Map<String, Integer>
Then in the code, I am adding entries to the collection :
map.put("> 80", // some stream() + lambda based logic for calculating the value part);
map.put("60 - 80", ....);
map.put("40 - 60", ....);
map.put("20 - 40", ....);
map.put(" < 40", ....);
Later in the debug mode, I see that the ordering of the keys have changed. For e.g. "20 -40" is first, "60- 80" is last. Why is the ordering of keys changing? How can I maintain the ordering of keys in the collection.

If you want the ordering of the keys to be maintained you should use a LinkedHashMap which, by default, iterates over the keys according to their insertion order.

Related

Sort a hashmap and get a key in an order (2nd key, 3rd, etc.) [duplicate]

This question already has answers here:
java HashMap sorting <String,Integer> . How to sort it? [duplicate]
(4 answers)
Sort a Map<Key, Value> by values
(64 answers)
Closed 1 year ago.
I have a HashMap<String, Integer> list and I want to sort it by integers and be able to get a key in a certain order (for example: get the 3rd, or 5th key).
How do I go by doing this?
You can't sort a HashMap. The order of entries within a HashMap is kinda random.
You could use myMap.keySet() to extract the keys (in random order) and put them in a new ordered collection (= List or SortedSet), for example: new ArrayList<>(myMap.keySet());. And then sort this List.
Or you use a SortedMap with a custom Comparator instead of a HashMap.

Does LinkedHashMap#put keep order when key is override? (JAVA) [duplicate]

This question already has answers here:
Java LinkedHashMap replace key
(2 answers)
Closed 5 years ago.
Here would be a LinkedHashMap, imagine it had many values inside of it.
LinkedHashMap map = new LinkedHashMap<>();
My question is, if one of the existing values was, for example, at index 4 and the same key was .put into the map, will it simply replace the value and remain at 4? Or, will it add onto the end?
The documentation of LinkedHashMap explicitly points this out:
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. (A key k is reinserted into a map m if m.put(k, v) is invoked when m.containsKey(k) would return true immediately prior to the invocation.)
So the value is replaced, but the iteration order will remain the same. For your example, the entry with key 4 will remain at the same position for the iteration.

Java find multiple lowest key/value pairs in a hashmap [duplicate]

This question already has answers here:
How to sort a HashMap in Java [duplicate]
(17 answers)
Closed 6 years ago.
I have a small HashMap (less than 100 entries) that contains a unique object (of my design) as the key and a Double as the value.
I need to retrieve n number of objects that have the lowest values.
So say my HashMap looked like this and I wanted the lowest 3.
Object, 4.0
Object, 5.0
Object, 2.0
Object, 12.0
Object, 10.0
Object, 3.0
I would want to fetch the first, third, and last entries as those have the lowest values.
I know there are methods such as Collections.min which I could run on the HashMap but I need more than just the lowest value and I need to know the key it corresponds to as well. Research has also led me to come across Selection Algorithms but I am confused and not quite sure how to use these. I apologise if a question of this sort has been asked before, I searched for a long time and could not find anything. Thanks pre-emptively for your help.
List<Entry<Key, Double>> lowestThreeEntries = map.entrySet()
.stream()
.sorted(Comparator.comparing(Entry::getValue))
.limit(3)
.collect(Collectors.toList());
Put all then entries of your map inside an array. Then, implement a Comparator<Map.Entry<Key,Value>> which compares the map entries according to the value they hold.
And finally, sort the entries of the map according to your shiny comparator. (You can use Arrays.sort)
Consider inverting your map and using a 'MultiMap' (effectively a more user friendly implementation of Map<Key, List<Value>>), the Guava TreeMultiMap should do exactly what you're after.
http://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/TreeMultimap.html
Edit - Added example (using String in place of the custom object for brevity)
TreeMultimap<Double, String> map = TreeMultimap.<Double, String>create();
map.put(4.0, "a");
map.put(5.0, "b");
map.put(2.0, "c");
map.put(12.0, "d");
map.put(10.0, "e");
map.put(3.0, "f");
Iterator<String> iterator = map.values().iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
This will print out the strings in ascending order according to the double value (c, f, a, b, e, d)

How to make sure the key's order can not be changed when traversing a HashMap in Java? [duplicate]

This question already has answers here:
How to preserve insertion order in HashMap? [duplicate]
(2 answers)
Closed 7 years ago.
For example,I input 3 Strings:Hagzou Hugzou Jigxng as the keys of a HashMap,
but when I traversing the HashMap by key,the order has been changed:Hugzou Hagzou Jigxng.
Is that possible to make sure the order can not be changed when output the keys?
like this:
input: Hagzou Hugzou Jigxng ###
output: Hagzou Hugzou Jigxng
thx a lot!
Here is my code:
HashMap< String, Integer > distance = new HashMap< String, Integer >();
Scanner input = new Scanner(System.in);
while (true) {
String city = input.next();
if (city.equals("###"))
break;
distance.put(city, null);
}
for (String city : distance.keySet()) {
System.out.println(city);
}
You can use LinkedHashMap:
Hash table and linked list implementation of the Map interface, with
predictable iteration order. This implementation differs from HashMap
in that it maintains a doubly-linked list running through all of its
entries. 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. (A key k is reinserted into a map m if
m.put(k, v) is invoked when m.containsKey(k) would return true
immediately prior to the invocation.)
In other words - while LinkedHashMap has a way to access entries by their hash code, like the regular HashMap it also maintains a doubly-linked list and maintain the order of the items insertion. This way when you use its iterator, you'll get the items at the same order you inserted them.

Retrieve key of Map by index [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Bi-directional Map in Java?
How can I retrieve key of Map by index when keys are not numeric and unordered ?
For example :
Map<String, Integer> test = new TreeMap<String, Integer>();
test.put("a", 1);
test.put("b", 2);
test.put("z", 3);
test.put("m", 4);
I want to get z if I have index 2 or a if I have index 0.
I know I can do dirty loop with increment to get it but is there another smart way to do it ?
What makes this a bit confusing is whether you're referring to the index based on the order the item is added, or based on the natural ordering of the key (eg: alphabetical)
You can obtain the list of may keys using map.keySet() but there's no guarantee the key set will be in the order which you add it in
You can use TreeMap instead of HashMap if you want to keep your data in some kind of ordering (eg: alphabetical ordering). If you prefer other way of ordering you can implement your own comparator

Categories