java.util.Arrays.useLegacyMergeSort=true 作用


(原)

今天看了一下現場的環境,發現有個其它部門的項目用到了這樣一個參數:

-Djava.util.Arrays.useLegacyMergeSort=true

  

於是查看了一下什么作用。

在JDK1.6和JDK1.7的版本中,使用comparator排序可能在1.6版本中正常運行,而在1.7版本有時會報異常,IllegalArgumentException(異常的內容大概是:Comparison method violates its general contract!)。

在JDK7的不兼容列表中,可以看到這樣一條消息:

Area: API: Utilities  
Synopsis: Updated sort behavior for Arrays and Collections may throw an IllegalArgumentException  
Description: The sorting algorithm used by java.util.Arrays.sort and (indirectly) by java.util.Collections.sort has been replaced.   
The new sort implementation may throw an IllegalArgumentException if it detects a Comparable that violates the Comparable contract.   
The previous implementation silently ignored such a situation.  
If the previous behavior is desired, you can use the new system property, java.util.Arrays.useLegacyMergeSort,   
to restore previous mergesort behavior.  
Nature of Incompatibility: behavioral  
RFE: 6804124 

大概意思就是 Arrays.sort方法和Collections.sort(底層也是Arrays.sort)方法被替換了,如果違反了新的排序規則就可能會出現IllegalArgumentException異常(這里是可能,不是一定)。之前的方法會忽略掉一種情況,如果想使用之前的方法,這里提供了一個新的參數,java.util.Arrays.useLegacyMergeSort去還原之前的方法。

再來看看Arrays.sort的實現

它是有二種排序方法,legacyMergeSort和TimSort。

舊的排序方式為legacyMergeSort,新的為TimSort,如果要用舊的排序方式,可以在系統屬性中加上 java.util.Arrays.useLegacyMergeSort=true 這個參數。

再看看Collections.sort方法的說明

大概意思新的TimSort排序方法的實現需要滿足三種情況:

  • sgn(compare(x, y)) == -sgn(compare(y, x))
  • ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0
  • compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z)) for all z

對於函數sgn(compare(x,y)),由於compare(x,y)的返回結果有0、1、-1三種,sgn(x)的結果也有三種,

1、當compare(x,y) < 0 時,sgn(compare(x,y))結果為-1

2、當compare(x,y) = 0 時,sgn(compare(x,y))結果為0

3、當compare(x,y) > 0 時,sgn(compare(x,y))結果為1

最容易出錯的情況就是自己寫的比較器只寫了1和-1的情況,而沒有寫0,如:

return x > y ? 1 : -1; 

這樣會導至當x == y時,compare(x,y)的結果為 -1,此時sgn(compare(x,y)) = -1,這與第一種滿足條件sgn(compare(x, y)) == -sgn(compare(y, x))相違背。所以會拋出IllegalArgumentException異常。

對於 x > y ? 1 : -1 ,當x == y時,也只是可可能會拋出異常,什么會拋出該異常,這要取絕於TimSort算法。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM