Java中关于Arrays.sort的两种重载方法的理解
前言
在java中重載排序方法的方法目前有兩種,一種是實現Comparable接口的compareTo方法,還有一種是用比較器(comparator) 作為參數,其中比較器是實現了Comparator接口的類的實例
類比于C++來看,重載排序方法實質上就是重載類的小于號,但是java標準中沒有規定可以重載運算符,所以需要用接口實現這個過程
同樣是類比C++,上述的兩種方法分別對應著重載小于號的函數作為成員函數和友元函數的區別,而其各自的優點分別是:
關于這兩種比較方法的語法網上一搜一大堆,我也就不多說了,重點是想記錄一下個人的一些理解
1.實現Comparable接口的compareTo方法
class Node implements Comparable<Node> {private int x,y;@overridepublic int compareTo(Node t){if(x!=t.x) return x-t.x;return y-t.y;} }先放上代碼,Node類只有兩個字段,排序方法首先以 x 進行排序,如果 x 相等的話再以 y 進行排序,下面是一些問題:
答:主要原因在于Java是一種強類型語言,在調用方法的時候,編譯器要能檢查這個方法確實存在,而在sort內部會出現這種語句:
// approach used in the standard library -- not recommended if(((Comparable) a[i]).compareTo(a[j]) > 0) {// rearrange a[i] and a[j]... } //call in main Arrays.sort(a);其中Arrays.sort的參數是Object[]類型,在內部進行比較的過程中,會將元素強制轉換為Comparable接口類型,然后調用其compareTo方法,所以需要對相應元素的類內實現Comparable接口的compareTo方法
答:因為能用到compareTo的地方實際上非常少,在Object類中預留方法會非常浪費
答:實際上上述方法理論上是可行的,但現實中為了讓接口統一標準,且許多類的內都用到了Object對象,所以用Object[]作為參數顯然更符合通用型的習慣
答:理論上是可行的,但代碼實現復雜度遠大于實現Comparable接口。提供元素的實例無非是為了強制轉換,但考慮到這種重載排序的方法有一個很大的優點是可以對同一父類的任意子類比較大小,其原理用到了對象引用的多態性,這里不多贅述(懂的都懂)所以如果想要顯式強制轉換的話,對同一類型的排序會方便很多;但是對于不同類型的排序,就會顯得有點笨拙了。
2.用比較器作為參數
class cmp implements Comparator<Node> {public int compare(Node a,Node b){if(a.x!=b.x) return a.x-b.x;return a.y-b.y;} } //call in main Arrays.sort(a,new cmp());這種重載排序的方法是為了給那些在類內沒有實現Comparable接口,但又想實現自定義排序的情況下準備的。
不過這種方法比較簡單,沒什么好說的。結合后續lambda表達式以及函數式接口的知識,不難發現這種方法傳遞的Comparator接口實例完全可以用lambda表達式的一句話代替,寫起來可讀性強,而且代碼復雜度低
平時算法競賽中的重載排序應該都會選擇這種方法,無非就是好寫,如下所示
//call in main Arrays.sort(t,(Node a,Node b)-> {if(a.x!=b.x) return a.x-b.x;return a.y-b.y; });后記
因為在學習重載排序時遇到了一些底層的小問題,在請教過zx學長以及啃博客之后才稍微理清楚了其原理,所以寫博客記錄一下,如有錯誤歡迎指正
總結
以上是生活随笔為你收集整理的Java中关于Arrays.sort的两种重载方法的理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CodeForces - 724C Ra
- 下一篇: Java GridBagConstrai