I have this Hashmap of floats and I want to get the top 5 largest values from it:
import java.util.Map;
HashMap<Float,Float> hm = new HashMap<Float,Float>();
// Putting key-value pairs in the HashMap
for (int i = 0; i < 100; i++) {
float pos = random(-50, 50);
float time = random(0, 50);
hm.put(time, pos);
}
// Using an enhanced loop to interate over each entry
for (Map.Entry me : hm.entrySet()) {
print("key is " + me.getKey());
println(" value is " + me.getValue());
}
I assume I would need to sort it first. Question is, how to sort it and will the keys still remain the same after the sort? When I say "same" I mean will the sorted values still have the original key identifier? This is crucial for what I am trying to accomplish.
If it is possible, replace HashMap
by an implementation of NavigableMap , such as TreeMap
. The iteration order of a HashMap
is undefined.
With a NavigableMap
you can sort it from higher to lower values by means of;
for (Map.Entry me : tm.descendingMap().entrySet() ()) {
System.out.print("key is " + me.getKey());
System.out.println(" value is " + me.getValue());
}
It is worth noting that descendingMap()
does not actually sort the contents of the map (because the TreeMap
is already sorted), but just return a reverse view of the original map.
This code does what you do. I developed and tested it in Processing IDE.
import java.util.Comparator;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.List;
class FloatEntryComparator implements Comparator<Map.Entry> {
public int compare(Map.Entry e1, Map.Entry e2) {
return ((Float)e2.getValue()).intValue() - ((Float)e1.getValue()).intValue();
}
}
void setup() {
Map<Float,Float> hm = new HashMap<Float,Float>();
// Putting key-value pairs in the HashMap
for (int i = 0; i < 100; i++) {
float pos = random(-50, 50);
float time = random(0, 50);
hm.put(time, pos);
}
println("ALL ENTRIES, UNSORTED:");
for (Map.Entry me : hm.entrySet()) {
print("key is " + me.getKey());
println(" value is " + me.getValue());
}
List<Map.Entry> entries = new ArrayList<Map.Entry>(hm.entrySet());
java.util.Collections.sort(entries, new FloatEntryComparator());
hm = new LinkedHashMap<Float, Float>();
for(Map.Entry e : entries)
hm.put((Float)e.getKey(), (Float)e.getValue());
println("5 LARGEST ENTRIES:");
int shownCount = 0;
for (Map.Entry me : hm.entrySet()) {
if(shownCount == 5)
break;
print("key is " + me.getKey());
println(" value is " + me.getValue());
++shownCount;
}
}
Explanation:
class FloatEntryComparator implements Comparator<Map.Entry> { ... }
~ here we declare so-called comparator, a class used for sorting a list in a specific order.
void setup() { ... }
~ if I understand it right, this is one of entry points for Processing script. Since we are not drawing anything, we don't implement draw function (yet), only setup.
Map<Float,Float> hm = new HashMap<Float,Float>();
for(...) ...
~ this is initialization part, same as in your code.
List<Map.Entry> entries = new ArrayList<Map.Entry>(hm.entrySet());
~ here hashmap is converted to a list of entries
java.util.Collections.sort(entries, new FloatEntryComparator());
~ here list of entries is sorted by values in descending order
hm = new LinkedHashMap<Float, Float>();
for(Map.Entry e : entries)
hm.put((Float)e.getKey(), (Float)e.getValue());
~ here list of entries is converted to hashmap. The resulting hashmap is sorted by values in descending order.
Here is the complete Processing script, tested against Processing 2.1:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.