按值大小排序地图

时间:2017-08-08 07:53:29

标签: java sorting dictionary collections compare

我只有一个简单的比较方法,可以按照值的大小对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!为什么这样?

2 个答案:

答案 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
}