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)
Related
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.
This question already has answers here:
Java Class that implements Map and keeps insertion order?
(8 answers)
Closed 5 years ago.
I have a HashMap to store my data of <Integer, ArrayList<String>>. I used put(...) to add data in the map if it does not exist yet. I used containsKey() to check if the entry is Key is already in the map. If it exists, I add the String to the key by doing this:
x.get(i).add(str)
To get the data, I just did a for loop with the keySet() of the hash.
If I have this hash:
int -> array of strings
1 -> "a", "b", "c"
2 -> "aa", "bb", "cc"
3 -> "aaa", "bbb", "ccc"
My problem is, the order of the data being read is not consistent.
In 1 PC, it might read the keys in this order: 2, 1, 3. In another PC, it might read it in this order: 1, 2, 3.
I would prefer that the order in which they are read are the same across all PCs. The order into which they are entered into the hashmap is also the same, but Why is the hashmap reading the Keysets in different order?
Did you read the Javadoc of HashMap? It makes no guarantees about ordering.
This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
If you want consistent ordering, use LinkedHashMap or TreeMap. HashMap's lack of guarantees mean that, if the Java developers choose, it can iterate backwards on Tuesdays.
Actually there is no way to control the input order of the elements in Hash Map, but it is possible to sort them before porcess them.
public class HashMapSample {
public static void main(String[] args) {
Map<Integer,List<String>> myHash = new HashMap<>();
myHash.put(1, Arrays.asList("a","aa","aaa"));
myHash.put(3, Arrays.asList("c","ccc","ccc"));
myHash.put(2, Arrays.asList("b","bb","bbb"));
System.out.println(myHash);
myHash.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey)).forEach(System.out::println);
}
}
You need to use TreeMap instead of HashMap
I'm sorry if this question was already asked, but i don't fine an answer to my question.
I'm working on HashMap i put two values (7,"value test 1") (7,"value test 2)
According to the specification java API HashMap put the first values is replaced by the second .
My question is when comes the resolution of collision ? why my second value is not store in linkedList or store in another place in the hashMap ? Is it due to the equals or hascode method ??
Best Regards
This has nothing to do with hash collision. Hash collisions (ie., keys with the same hashcode()) are handled correctly by the HashMap. In your example, both keys are equal (ie., 7.equals(7) == true), so the old value is replaced.
In the following example
Map<Integer, String> map = new HashMap<>();
map.put(7, "value 1");
map.put(7, "value 2");
System.out.println(map.get(7));
what would you expect in the last line to happen?
Maybe you are looking for a multimap?
Apache Commons
Guava
Stackoverflow
Collision handling takes place if two different keys resolve to the same bucket in the hashmap. In that case the second entry would be put into the linked list.
In your case you replace the entry for the same key (7) and thus there is no collision.
If you need a map that contains multiple values per key either use a Map<key, Set<value>> (you can also use a List etc. instead of a Set) and handle adding/removing to that set yourself or use Apache Commons' MultiMap or Google Guava's Multimap, e.g. HashMultimap.
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
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
ordered map implementation
I am using the hashmap to store the values as follows -
Map<String,String> propertyMap=new HashMap<String,String>();
propertyMap.put("Document Type", dataobject.get("dDocType"));
propertyMap.put("Document Title", dataobject.get("dDocTitle"));
propertyMap.put("Revision Label", dataobject.get("dRevLabel"));
propertyMap.put("Security Group", dataobject.get("dSecurityGroup"));
After that i am getting the hashmap key and value in a List
documentProperties = new ArrayList(propertyMap.entrySet());
But when i iterate over the List i am not getting the key and values in the order i have put it into the map..
Is there is anyway by which i can get the values in the Order i am putting it into the map.
Thanks
I believe what you are looking for is LinkedHashMap.
This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).
By the why, why the need for a separate ArrayList? You can directly iterate over Map.entrySet:
for (final Map.Entry<String, String> entry : propertyMap.entrySet()) {
...
}
propertyMap.entrySet() you get results as Set. Set is un-ordered.
new ArrayList(propertyMap.entrySet()); constructs a list with the order you have in Set (which may not be the order you have put into map).
If you are looking for order map, you may use LinkedHashMap
Here is interesting discussion on this topic.
You have to use LinkedHashMap. For more details Please check this question and answer given by Michael
Try this..
for(Map.Entry<String, String> m : map.entrySet()){
// Use m.getKey() to get the Key.
// Use m.getValue() to get the Value.
}