我知道,已经多次询问过这个问题,但帮助我理解了一些事情。
您有一张需要按价值
排序的地图 Map<String, Integer> m = new HashMap<String, Integer>();
m.put("a", 1);
m.put("b", 13);
m.put("c", 22);
m.put("d", 2);
你调用一种方法来实现它
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;
}
你有一个比较器类
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;
}
这段代码显然是有缺陷的。请帮我理解原因?
答案 0 :(得分:2)
if (x > y)
return x;
if (y > x)
return y;
return 0;
如果1
,您应该返回x > y
,如果-1
则返回y > x
。 Comparator
合约指定如果第一个值小于第二个值则返回负数,如果第一个值大于第二个值则返回正数,如果它们相等则返回零。
(请注意,如果你曾经碰巧使用原始地图中没有的值,这个Comparator
实现会以非常混乱的方式破解。)
更好的是,只需返回Integer.compare(x, y)
,即可完成所有这些操作。 (但是只在Java 7中。)
答案 1 :(得分:1)
@Override
public int compare(String a, String b) {
Integer x = m.get(a);
Integer y = m.get(b);
return x.compareTo(y);
}
由于您将Integer对象作为值,因此可以使用隐式方法比较对象并返回1,0或-1。
答案 2 :(得分:0)
比较器不会返回更大或更小的值。它们返回一个负值,表示小于或正值表示大于。
if (x > y)
return x;
if (y > x)
return y;
return 0;
应该是
if (x > y)
return -1;
if (y > x)
return 1;
return 0;
答案 3 :(得分:0)
您的比较器仅表示值相等或左侧大于右侧。
考虑x
为1且y
为2的情况。比较器将返回2 - 正数 - 当它应该返回负数时。
我建议你再次学习the Comparator
interface documentation,看看你错过了合同的哪一部分。
答案 4 :(得分:0)
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;
}