C. *_*nig 3 java comparator java-8
我有以下异常,我不太清楚为什么:
java.lang.IllegalArgumentException:比较方法违反了它的一般合同!
在java.util.TimSort.mergeLo(TimSort.java:777)java.util.TimSort.mergeAt(TimSort.java:514)java.util.TimSort.mergeCollapse(TimSort.java:441)java.util. TimSort.sort(TimSort.java:245)java.util.Arrays.sort(Arrays.java:1512)at java.util.ArrayList.sort(ArrayList.java:1454)
我编写了以下JUnit测试来验证行为:
@Test
public void testComparator() {
List<Boolean> item = new ArrayList<>();
item.add(true);
for (int i = 0; i < 1000000; i++) {
item.add(false);
}
while(true) {
System.out.println("Sorting");
Collections.shuffle(item);
item.sort((lineItem1, lineItem2) -> {
if (lineItem1 && lineItem2) {
return 0;
} else if (!lineItem1) {
return 1;
} else if (!lineItem2 ) {
return -1;
}
return 0;
});
}
}
Run Code Online (Sandbox Code Playgroud)
如果我交换返回1并返回-1,它会突然无效.但为什么?这应该只改变排序顺序而不是破坏整个比较器.
我错过了什么?
你比较器违反了合同,因为当两个参数都是时false,它将1由于语句而返回if (!lineItem1) { return 1; }….
一般来说,没有保证TimSort会发现不正确的比较器,它没有主动尝试查找合同违规,它只是检测某些情况作为算法的副作用.
你真正想要的是什么
item.sort((lineItem1, lineItem2) -> {
if (lineItem1.equals(lineItem2)) {
return 0;
} else if (!lineItem1) {
return 1;
} else {
return -1;
}
});
Run Code Online (Sandbox Code Playgroud)
虽然你可以实现同样的使用
item.sort((lineItem1, lineItem2) -> lineItem1^lineItem2? lineItem1? -1: 1: 0);
Run Code Online (Sandbox Code Playgroud)
甚至更简单
item.sort(Comparator.reverseOrder());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
380 次 |
| 最近记录: |