排序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 楼答案
你给出的最后一个区块作为违反合同的例子是错误的,原因如下
例如,如果我们有两个元素
a = (5, 1)
和b = (5, 1)
,其中我将每个元素表示为(freq, n)
的元组,然后比较a
和b
返回-1
,指定a
必须早于排序列表中的b
。然而,如果我们以相反的顺序b
和a
比较这两个值,给定的示例仍然会返回-1
,这一次表示b
必须早于a
我认为,当
freq
和n
相等时,显式地处理返回0
应该可以修复最后一段代码