Reputation: 96421
This has been asked several times, i know, but help me understand something.
You have a map you need sorted by Value
Map<String, Integer> m = new HashMap<String, Integer>();
m.put("a", 1);
m.put("b", 13);
m.put("c", 22);
m.put("d", 2);
You call a method to make it happen
public static List<String> sortByValue(final Map<String, Integer> unsortedMap) {
List<String> sortedKeys = new ArrayList<String>();
sortedKeys.addAll(unsortedMap.keySet());
Collections.sort(sortedKeys, new MapComparator(unsortedMap));
return sortedKeys;
}
You have a comparator class
public MapComparator(Map<String, Integer> m) {
this.m = m;
}
@Override
public int compare(String a, String b) {
int x = m.get(a);
int y = m.get(b);
if (x > y)
return x;
if (y > x)
return y;
return 0;
}
This code, obviously is flawed. Please help me understand why?
Upvotes: 0
Views: 115
Reputation: 32004
public static List<String> sortByValue(final Map<String, Integer> unsortedMap) {
List<String> sortedKeys = new ArrayList<String>();
sortedKeys.addAll(unsortedMap.keySet());
Collections.sort(sortedKeys, new Comparator<String>(){
public int compare(String s1, String s2) {
return unsortedMap.get(s1).compareTo(unsortedMap.get(s2));
}});
return sortedKeys;
}
Upvotes: 0
Reputation: 31
@Override
public int compare(String a, String b) {
Integer x = m.get(a);
Integer y = m.get(b);
return x.compareTo(y);
}
Since you have Integer objects as values, you can use the implicit method to compare the objects and return 1, 0 or -1.
Upvotes: 1
Reputation: 15259
Your comparator only ever indicates that the values are equal or that the left is greater than the right.
Consider the case where x
is 1 and y
is 2. Your comparator will return 2—a positive number—when it should have returned a negative number.
I recommend that you study the Comparator
interface documentation again to see which part of the contract you're missing out on here.
Upvotes: 0
Reputation: 120516
Comparators don't return the greater or lesser value. They return a negative value to indicate less-than or a positive value to indicate greater than.
if (x > y)
return x;
if (y > x)
return y;
return 0;
should probably be
if (x > y)
return -1;
if (y > x)
return 1;
return 0;
Upvotes: 0
Reputation: 198143
if (x > y)
return x;
if (y > x)
return y;
return 0;
You should be returning 1
if x > y
and -1
if y > x
. The Comparator
contract specifies that you return a negative number if the first value is less than the second, a positive number if the first is greater than the second, and zero if they're equal.
(Mind you, as it stands, this Comparator
implementation will break in very confusing ways if you ever happen to use values that aren't in the original map.)
Better yet, just return Integer.compare(x, y)
, which does all that for you. (Only in Java 7, though.)
Upvotes: 2