I need to sort a 2d key/value pair by the value. I have read many references about this on the web and have ended up writing my own class to do this using HashMaps(see below). I put the code into a condensed working class that reproduces the problem with the minimum amount of code so that you can just cut and paste it into your IDE for quick diagnostics.
As you can see, the method that I wrote is correctly sorting the values before they are entered into sortedMap. However, for some reason, they values are then again unordered in a different way when I try to subsequently iterate through sortedMap.
Can anyone show me how to fix the code below so that I iterate through a resulting 2D data object that gives me my data in descending order?
import java.util.*;
public class HashMapDemo {
public static void main(String args[]) {
// Code that creates and populates the unordered HashMap:
TreeMap<Integer, Double> unSortedMap = new TreeMap<Integer, Double>();
unSortedMap.put(1343, 0.521851);
unSortedMap.put(1950, -0.301208);
unSortedMap.put(3667, -0.0280762);
unSortedMap.put(3879, 0.154724);
unSortedMap.put(4124, 0.022583);
// Code that calls the ordering method:
TreeMap<Integer, Double> sortedMap = new TreeMap<Integer, Double>(
sortTreeMap(unSortedMap));
// Code that iterates through the "sorted" hashmap.
System.out.println("now iterate through sortedMap: ");
for (Integer key : sortedMap.keySet()) {
System.out.println("key, sortedMap.get(key) are: " + key + ", "
+ sortedMap.get(key));
}
}
// Code for the ordering method. Note that the println tests indicate that
// this method is correctly sorting the key/value pairs in the hashmap:
private static TreeMap<Integer, Double> sortTreeMap(
TreeMap<Integer, Double> input) {
System.out
.println("input.size() upon entering sortHasMap() function is: "
+ input.size());
int startSize = input.size();
// create a hashmap to store sorted output
TreeMap<Integer, Double> sortedMap = new TreeMap<Integer, Double>();
// repeat the following process once for every key/value pair in the
// hashmap
for (int i = 0; i < startSize; i++) {
int mySize = input.size();
System.out.println("mySize is: " + mySize);
double maxVal = Double.NEGATIVE_INFINITY;
int maxKey = 0;
// iterate through each key in hashmap to find key/value of max
// value
for (Integer key : input.keySet()) {
if (maxVal < input.get(key)) {
maxVal = input.get(key);
maxKey = key;
}
}
// add key/value of max of that iteration to sorted map and remove
// from input before next iteration
sortedMap.put(maxKey, maxVal);
input.remove(maxKey);
System.out.println("sortedMap.put(maxKey, maxVal) are: " + maxKey
+ ", " + maxVal);
}
return sortedMap;
}
}
You need only two lines to achieve what you want. Here are those two lines:
Map<Integer, Double> sortedMap = new TreeMap<Integer, Double>(new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return map.get(o2).compareTo(map.get(o1)); // reverse order of values
}
});
sortedMap.putAll(map);
Here's the complete runnable code:
public static void main(String[] args) {
final Map<Integer, Double> map = new HashMap<Integer, Double>();
map.put(1343, 0.521851);
map.put(1950, -0.301208);
map.put(3667, -0.0280762);
map.put(3879, 0.154724);
map.put(4124, 0.022583);
Map<Integer, Double> sortedMap = sortMap(map);
for (Map.Entry<Integer, Double> entry : sortedMap.entrySet()) {
System.out.println(entry.getKey() + ", " + entry.getValue());
}
}
public static Map<Integer, Double> sortMap(final Map<Integer, Double> map) {
Map<Integer, Double> sortedMap = new TreeMap<Integer, Double>(new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return map.get(o2).compareTo(map.get(o1));
}
});
sortedMap.putAll(map);
return sortedMap;
}
Output:
1343, 0.521851
3879, 0.154724
4124, 0.022583
3667, -0.0280762
1950, -0.301208
Notes: You specify how you want entries ordered in a TreeSet by passing the Comparator you want to use into the constructor. The TreeSet implementation does the rest.
Other notes:
Map.entrySet()
Map<?, ?> myMap
not the concrete implementation (ie HashMap<?, ?> myMap
) Here's the generic version of the sortMap
method that will sort any suitable map based on the reverse order of the values:
public static <K, V extends Comparable<V>> Map<K, V> sortMap2(final Map<K, V> map) {
Map<K, V> sortedMap = new TreeMap<K, V>(new Comparator<K>() {
public int compare(K o1, K o2) {
return map.get(o2).compareTo(map.get(o1));
}
});
sortedMap.putAll(map);
return sortedMap;
}
Use a TreeMap . Its a SortedMap
that uses the natural ordering of keys. In your case, it will order by the Integer
key.
It does the sorting for you.
java.util.HashMap is unordered.
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.
EDIT
After reading the question correctly
Use a Comparator for the TreeMap constructor that compares the values.
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.