I am attempting to sort a hashmap on type <Integer,Double> using a TreeMap and a SortedMap I want to sort on the absolute values of the Doubles but I also want to retain the sign value (hence not storing as an unsigned Double).
Below is the code I am using, however I am not getting the values I expect, presumably due to the use of hashcode() can anybody point out how to fix this?
Map<Integer,Double> termWeights = new HashMap<Integer,Double>();
SortedMap sortedData = new TreeMap(new ValueComparer(termWeights));
System.out.println(termWeights);
sortedData.putAll(termWeights);
System.out.println(sortedData);
class ValueComparer implements Comparator {
private Map _data = null;
public ValueComparer(Map data) {
super();
_data = data;
}
public int compare(Object o1, Object o2) {
Double e1 = Math.abs((Double) _data.get(o1));
Double e2 = Math.abs((Double) _data.get(o2));
int compare = e2.compareTo(e1);
if (compare == 0) {
Integer a = o1.hashCode();
Integer b = o2.hashCode();
return b.compareTo(a);
}
return compare;
}
}
Thanks
So what is the problem?
That looks correctly sorted from biggest to smallest.
But I would avoid using hashCode in the tie-break secondary comparator, because you need it to never return the same value for different inputs. In this case, it works, because you are calling it on an Integer, where hashCode just returns the same int. But if you used Long or String keys in your map, it would have collisions. Compare the two keys directly instead.
And finally, you must not change the weights after starting to use the comparator. That will lead to an inconsistent TreeMap.