有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

排序java。lang.IllegalArgumentException:比较方法违反了它的通用合同java。base/java。util。蒂姆索特。合并崩溃

class Solution {
    public int[] frequencySort(int[] nums) {
        ArrayList<Integer> list = new ArrayList<>();
        for (int i : nums) {
            list.add(i);
        }
        list = fun(list);
        for(int i=0;i<nums.length;i++){
            nums[i] = list.get(i);
        }
        return nums;
    }
    
    public ArrayList<Integer> fun(ArrayList<Integer> list){
        Map<Integer,Integer> map = new HashMap<>();
        
        list.forEach(i -> {
            map.put(i,map.getOrDefault(i,0)+1);
        });
        
        Collections.sort(list,(n1,n2) -> {
            int freq1 = map.get(n1);
            int freq2 = map.get(n2);
            
            if(freq1!=freq2){
                return freq1-freq2;
                // if(freq1>freq2){
                //     return 1;
                // }
                // return -1;
            }
            return n2-n1;
            //if(n1>=n2){
            //   return -1;
            //}
           // return 1;
            
        } );
        return list;
    }
}

//sample input : nums = [2,3,1,3,2]
//output : [1,3,3,2,2]

在有趣的方法中,在集合中。sort(),我根据频率的递增顺序对数组进行排序,如果两者的频率相同,那么我会按值的递增顺序添加它们。我从谷歌那里得到的上述代码运行良好,但我自己编写了几乎类似的代码,并将其作为注释包含在内。这两个代码看起来很相似,但我的代码(作为注释)只通过了85/150个测试用例,之后我得到了“java.lang.IllegalArgumentException:比较方法违反了它的一般约定!”

我发现了类似的问题,但我不能理解,有人用更简单的术语解释它

//This block I found in google

if(freq1!=freq2){
    return freq1-freq2;
 }
 return n2-n1;
//Below Block gives "Comparison method violates its general contract"

if(freq1!=freq2){
       if(freq1>freq2){
          return 1;
        }
       return -1;
}
if(n1>=n2){
       return -1;
}
return 1;

共 (1) 个答案

  1. # 1 楼答案

    你给出的最后一个区块作为违反合同的例子是错误的,原因如下

    例如,如果我们有两个元素a = (5, 1)b = (5, 1),其中我将每个元素表示为(freq, n)的元组,然后比较ab返回-1,指定a必须早于排序列表中的b。然而,如果我们以相反的顺序ba比较这两个值,给定的示例仍然会返回-1,这一次表示b必须早于a

    我认为,当freqn相等时,显式地处理返回0应该可以修复最后一段代码