java.lang.illegalargumentexception:比较方法违反了其一般约定java.base/java.util.timsort.mergecollapse

mfuanj7w  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(479)
  1. class Solution {
  2. public int[] frequencySort(int[] nums) {
  3. ArrayList<Integer> list = new ArrayList<>();
  4. for (int i : nums) {
  5. list.add(i);
  6. }
  7. list = fun(list);
  8. for(int i=0;i<nums.length;i++){
  9. nums[i] = list.get(i);
  10. }
  11. return nums;
  12. }
  13. public ArrayList<Integer> fun(ArrayList<Integer> list){
  14. Map<Integer,Integer> map = new HashMap<>();
  15. list.forEach(i -> {
  16. map.put(i,map.getOrDefault(i,0)+1);
  17. });
  18. Collections.sort(list,(n1,n2) -> {
  19. int freq1 = map.get(n1);
  20. int freq2 = map.get(n2);
  21. if(freq1!=freq2){
  22. return freq1-freq2;
  23. // if(freq1>freq2){
  24. // return 1;
  25. // }
  26. // return -1;
  27. }
  28. return n2-n1;
  29. //if(n1>=n2){
  30. // return -1;
  31. //}
  32. // return 1;
  33. } );
  34. return list;
  35. }
  36. }
  37. //sample input : nums = [2,3,1,3,2]
  38. //output : [1,3,3,2,2]

在collections.sort()的fun方法中,我根据频率的递增顺序对数组进行排序,如果两者的频率相同,那么我将按值的递增顺序添加它们。我从谷歌得到的上述代码运行良好,但我自己编写了几乎类似的代码,并将其作为注解包含在内。这两个代码看起来很相似,但我的代码(作为注解)只通过了85/150个测试用例,之后我得到了“java.lang.illegalargumentexception:comparison方法违反了它的一般约定!”
我发现了类似的问题,但我不能理解,有人用更简单的术语解释它!!!

  1. //This block I found in google
  2. if(freq1!=freq2){
  3. return freq1-freq2;
  4. }
  5. return n2-n1;
  1. //Below Block gives "Comparison method violates its general contract"
  2. if(freq1!=freq2){
  3. if(freq1>freq2){
  4. return 1;
  5. }
  6. return -1;
  7. }
  8. if(n1>=n2){
  9. return -1;
  10. }
  11. return 1;
628mspwn

628mspwn1#

您给出的最后一个区块作为违反合同的示例是错误的,原因如下。
例如,如果我们有两个元素 a = (5, 1)b = (5, 1) ,其中,我将每个元素表示为 (freq, n) ,然后进行比较 ab 返回 -1 指定 a 我必须早于 b 在已排序的列表中。但是,如果我们以相反的顺序比较这两个值-- ba ,给定的示例仍将返回 -1 这一次说, b 我必须早于 a .
我认为明确地考虑返回 0 如果两者都是 freqn 如果相等,则应修复最后一段代码。

相关问题