1. 程式人生 > >JDK1.7 Collections.sort排序異常

JDK1.7 Collections.sort排序異常

1、問題描述

從jdk1.6切換到jdk1.7專案編譯出現這個問題,報錯如下,原因時jdk1.7修改了排序演算法,與jdk1.6排序方法改變,Exception如下: 
java.lang.IllegalArgumentException: Comparison method violates its general contract!

2、產生問題程式碼

  1. Collections.sort(dataEdgePasses,newComparator<DataEdgePass>(){
  2. @Override
  3. publicint compare(DataEdgePass o1,DataEdgePass
    o2){
  4. return((o1.getEdgeLength()*18)/(o1.getTripTime()*5))-((o2.getEdgeLength()*18)/(o2.getTripTime()*5))>0?1:-1;
  5. }
  6. });

3、錯誤原因

這段程式碼放到1.6下編譯時沒問題的,jdk1.7報錯(沒考慮相等情況),1.7排序原則如下:

  1. a). sgn(compare(x, y))==-sgn(compare(y, x))
  2. b).(compare(x, y)>0)&&(compare(y, z)>0)意味著 compare(x, z)>0
  3. c). compare
    (x, y)==0意味著對於任意的zsgn(compare(x, z))==sgn(compare(y, z))均成立

如果相等情況,那麼就違反了第一條,1==-1,所以會報這種錯誤

4、問題處理

處理也很簡單,考慮到相等情況即可:

4.1、處理一

  1. publicint compare(ComparatorTest o1,ComparatorTest o2){
  2. return o1.getValue()== o2.getValue()?0:(o1.getValue()> o2.getValue()?1:-1);
  3. }

4.2、處理二

  1. Collections.sort(dataEdgePasses
    ,newComparator<DataEdgePass>(){
  2. @Override
  3. publicint compare(DataEdgePass o1,DataEdgePass o2){
  4. return((o1.getEdgeLength()*18)/(o1.getTripTime()*5))-((o2.getEdgeLength()*18)/(o2.getTripTime()*5));
  5. }
  6. });

4.3、處理三

繼續使用jdk1.6來編譯