復(fù)現(xiàn)
錯(cuò)誤代碼如下
Collections.sort(dataList, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 > o2 ? 1 : -1;
}
});
這里看著也沒(méi)啥問(wèn)題啊,相同的代碼運(yùn)行在不同手機(jī)上為啥有的報(bào)錯(cuò)有的不報(bào)錯(cuò)呢?根據(jù)錯(cuò)誤提示Comparison method violates its general contract!去查看源碼后找到拋出導(dǎo)致這個(gè)錯(cuò)誤代碼的具體位置
if (len1 == 1) {
assert len2 > 0;
System.arraycopy(a, cursor2, a, dest, len2);
a[dest + len2] = tmp[cursor1];
} else if (len1 == 0) {
throw new IllegalArgumentException("Comparison method violates its general contract!");
} else {
assert len2 == 0;
assert len1 > 1;
System.arraycopy(tmp, cursor1, a, dest, len1);
}
查閱相關(guān)資料后發(fā)現(xiàn)說(shuō)這種寫(xiě)法在Java JDK6中沒(méi)有問(wèn)題。在Java JDK6以后,Comparator要滿(mǎn)足自反性、傳遞性、對(duì)稱(chēng)性,不然Arrays.sort、Collections.sort會(huì)報(bào)IllegalArgumentException異常。說(shuō)明:
- 自反性:x,y 的比較結(jié)果和y,x的比較結(jié)果相反。
- 傳遞性:x > y,y > z,則x > z。
- 對(duì)稱(chēng)性:x = y,則x,z比較結(jié)果和y,z比較結(jié)果相同。
然而錯(cuò)誤寫(xiě)法:o1 > o2 ? 1 : -1,并沒(méi)有處理相等的情況,所以在實(shí)際使用中可能會(huì)出現(xiàn)異常。
斗羅小劇場(chǎng)
小舞:哥,這里我有個(gè)疑問(wèn)了,運(yùn)行的環(huán)境都是Java JDK8的,為啥有的手機(jī)不會(huì)閃退有的手機(jī)會(huì)閃退呢?
小三:額......這......
小三:小舞,哥現(xiàn)在修為等級(jí)還不夠,等我魂力到達(dá)90級(jí)或許可以幫你解決這個(gè)問(wèn)題!??!
總結(jié)
根據(jù)上面的分析,在Java JDK6以后,Comparator要滿(mǎn)足自反性、傳遞性、對(duì)稱(chēng)性。所以正確的寫(xiě)法應(yīng)該是
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
//return o1 - o2或者return o1.compareTo(o2)
return o1.compareTo(o2);
}
});