我收到以下错误:“比较方法违反了它的一般约定!” 当使用以下比较器时,但是我无法使用jUnit复制异常。我想知道是什么引起了这个问题以及如何复制它。有一些其他例子也有相同的问题,但没有类似的例子。
public class DtoComparator implements Comparator<Dto> {
@Override
public int compare(Dto r1, Dto r2) {
int value = 0;
value = r1.getOrder() - r2.getOrder();
if (value == 0 && !isValueNull(r1.getDate(), r2.getDate()))
value = r1.getDate().compareTo(r2.getDate());
return value;
}
private boolean isValueNull(Date date, Date date2) {
return date == null || date2 == null;
}
}
通过使用以下代码调用该代码:
``
Collections.sort(dtos, new DtoComparator());
```
谢谢你的帮助。
额外信息:该错误似乎发生在Java utils中的TimSort类中,以及发生在称为mergeLo的方法中。链接:http : //grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/TimSort.java#TimSort.mergeLo%28int%2Cint%2Cint%2Cint% 29
来自的文档compare
。
实施者必须确保sgn(x.compareTo(y)) == -sgn(y.compareTo(x))所有人x和y
基于减法的比较器不满足此条件。这是因为减法会溢出。例如
Integer.MIN_VALUE - 0
0 - Integer.MIN_VALUE
都是负面的。
您处理Dates的方式也有问题。从以下文档中compare:
最后,实现者必须确保x.compareTo(y)==0暗示sgn(x.compareTo(z)) == sgn(y.compareTo(z))所有z。
您的compare
方法打破了这一点。例如,如果x
是null,y
是1970年1月1日,并z
为1970年1月2日,然后
compare(x, y) == 0 // x == null
compare(x, z) == 0 // x == null
compare(y, z) == -1 // January 1st is before January 2nd.
我将编写方法如下:
@Override
public int compare(Dto r1, Dto r2) {
int value = Integer.compare(r1.getOrder(), r2.getOrder());
if (value != 0)
return value;
Date date1 = r1.getDate();
Date date2 = r2.getDate();
if (date1 == null && date2 == null)
return 0;
if (date1 == null)
return -1;
if (date2 == null)
return 1;
return date1.compareTo(date2);
}
我设法重现了这个问题,但List至少只持续了s个32。请参阅此链接以获取为什么List至少32需要一个大小a的解释。为什么使用Collections.sort的该程序仅对大小为32或更大的列表失败?
public class Main {
private static final class NumAndDate {
private final int num;
private final Date date;
NumAndDate(int num, Date date) {
this.num = num;
this.date = date;
}
}
public static final class NumAndDateComparator implements Comparator<NumAndDate> {
@Override
html" target="_blank">public int compare(NumAndDate r1, NumAndDate r2) {
int value = 0;
value = r1.num - r2.num;
if (value == 0 && !isValueNull(r1.date, r2.date))
value = r1.date.compareTo(r2.date);
return value;
}
private boolean isValueNull(Date date, Date date2) {
return date == null || date2 == null;
}
}
public static void main(String[] args) {
NumAndDate[] array = {
new NumAndDate(0, new Date(0)),
new NumAndDate(0, new Date(1)),
new NumAndDate(0, null)
};
Random random = new Random();
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 10000; j++) {
List<NumAndDate> list = new ArrayList<>();
int[] arr = new int[i];
for (int k = 0; k < i; k++) {
int rand = random.nextInt(3);
arr[k] = rand;
list.add(array[rand]);
}
try {
Collections.sort(list, new NumAndDateComparator());
} catch (Exception e) {
System.out.println(arr.length + " " + Arrays.toString(arr));
return;
}
}
}
}
}
我看到我的应用程序在一些中国 Android 手机上发生了很多崩溃,并出现错误:比较方法违反了其总合同! 我读过这与Collections.sort有关。 我不太确定的是,这是否是因为我的自定义比较器。 以下是错误发生的地方: 比较器是这样的: 所以我不太确定比较器是否搞砸了什么,或者我是否需要以不同的方式进行collections.sort调用 感谢任何帮助
我收到以下错误:“比较方法违反了它的一般合同!”当使用下面的比较器时,我无法使用jUnit复制异常。我想知道是什么导致了这个问题,以及如何复制它。有其他人也有同样的问题,但不知道如何复制。 使用以下方法调用该代码: 感谢任何帮助。 额外信息:该错误似乎发生在Java utils中的TimSort类中,并来自一个名为mergeLo的方法。链接:http://grepcode.com/file/rep
我有一个类字段,和。我需要使用对它们进行排序,但我得到了一个异常: java.lang.IllegalArgumentException:比较方法违反了它的一般约定! 我的< code>compareTo方法: 请帮我找出compareTo方法中的错误。谢了。
我在尝试对节点的数组列表进行排序时遇到了这个错误。我尝试了大多数解决方案,但没有一个在我的案例中有效。 此代码为 它适用于小输入,但是当输入数量很大时,它会给出这个错误。我也读过比较方法中的传递性规则,但我不知道它是如何在这种情况下应用的。 先谢谢你。
我目前正在Java中对集合进行排序。我收到了错误消息“比较方法违反了它的一般契约”。我也理解这个错误消息,但我(主要)使用Long类型的构建比较方法。所以我不知道,在这种情况下,排序方法仍然违反了契约。这是我的代码: 这里是错误:
下面的代码在Java 6上运行时抛出“Java比较方法违反了它的通用契约”。但是,在Java 7上,它不会抛出同样的异常。有什么问题?。如何修改这段代码以在Java 7上抛出异常?。