我只有一个简单的比较方法,可以按照值的大小对Map
进行排序。
public List<Entry<String, HashSet<String>>> orderByDescStringSetSize(HashMap<String, HashSet<String>> map){
Set<Entry<String, HashSet<String>>> set = map.entrySet();
List<Entry<String, HashSet<String>>> list = new ArrayList<Entry<String, HashSet<String>>>(set);
Collections.sort(list, new Comparator<Map.Entry<String, HashSet<String>>>(){
public int compare(Map.Entry<String, HashSet<String>> o1, Map.Entry<String, HashSet<String>> o2){
Integer o1Vals = o1.getValue().size();
Integer o2Vals = o2.getValue().size();
//descending
if(o2Vals > o1Vals)
return 1;
else if(o2Vals==o1Vals)
return 0;
else
return -1;
}
});
return list;
}
我得java.lang.IllegalArgumentException: Comparison method violates its general contract
!为什么这样?
答案 0 :(得分:2)
这是因为o2Vals==o1Vals
没有达到预期效果。
您正在使用Integer
对象 - 请使用equals
!!
这可能不是唯一的问题。
答案 1 :(得分:0)
使用您所做的相同方法我将修改:
HashSets
的尺寸为int
,用于比较而不是Integer
。if else if else
。此外,您只需返回减去的值:return o2Vals - o1Vals
。 Entry
Map.Entry
,您确定拥有正确的导入吗?在任何情况下,我建议您始终使用其中一个来确保类型相同。 这就是说,解决方案应该是这样的:
public List<Entry<String, HashSet<String>>> orderByDescStringSetSize2(HashMap<String, HashSet<String>> map) {
Set<Entry<String, HashSet<String>>> set = map.entrySet();
List<Entry<String, HashSet<String>>> list = new ArrayList<>(set);
Collections.sort(list, new Comparator<Entry<String, HashSet<String>>>() {
@Override
public int compare(Entry<String, HashSet<String>> o1, Entry<String, HashSet<String>> o2) {
int o1Vals = o1.getValue().size();
int o2Vals = o2.getValue().size();
// Descending
return o2Vals - o1Vals;
}
});
return list;
}
但是,如果您使用的是Java 8,则可以利用Stream
界面并在不定义Comparator
的情况下更紧凑:
public List<Entry<String, HashSet<String>>> orderByDescStringSetSize(HashMap<String, HashSet<String>> map) {
return map.entrySet().stream() // Create stream
.sorted(Comparator.comparing(entry -> -((Entry<String, HashSet<String>>) entry).getValue().size())) // Sort descending
.collect(Collectors.toList()); // Collect
}