5 分鐘搞定 Java Comparable 介面
本文由碼農網 – 小峰原創翻譯,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃!
這篇文章是免費Java 8 課程中關於Clean Code原則的一部分。
在這篇文章中,我們要聊一聊Java Comparable介面。
還有一個不錯的視訊可以點這裡。
Comparable介面時用來幹什麼的呢?
我們應該如何對事物進行比較和排序?這問題聽上去有點莫名其妙,但我希望你認真考慮一下。比方說,我們有一組蘋果:
例1
我們要怎樣對它們進行排序呢?我們希望通過重量進行排序嗎?如果是的話,排序是從最輕到最重還是從最重到最輕?當我們對它們進行排序的時候,我們需要反覆比較兩個蘋果的重量,直到正確地排好所有的蘋果。蘋果1比蘋果2重?那它比蘋果3重嗎?我們需要不斷比較,直到完成排序。Comparable介面可以幫助我們實現這一目標。Comparable本身不能對物件進行排序,但介面定義的方法 int compareTo(T)可以。
compareTo(T)如何工作
讓我們通過使用compareTo()方法來看看哪個蘋果更重,開始吧。
例2
compareTo()方法的工作原理是返回一個int值——或正,或負,或為零。它通過呼叫作為引數的物件來比較物件。負數表示呼叫的物件比引數“輕”。如果我們用大小來比較蘋果,那麼上面的呼叫會返回一個負數,例如-400,因為紅蘋果比青蘋果小。如果兩個蘋果重量相等,那麼呼叫將返回0。如果紅蘋果更重,那麼compareTo()將返回一個正數,例如68。
compareTo()的靈活性
如果我們反覆呼叫上面的compareTo()方法,那麼我們可以通過大小來排序,這很棒,但並非故事的結束。如果我們想通過顏色來給蘋果排序呢?抑或是重量?我們也可以做到。關鍵是,我們的客戶——讓我們叫他胖子農夫(見例3),需要在我們開始開發之前精確定義需要如何對蘋果進行排序。
例3
他可以通過回答這兩個問題來做到這一點:
- 他希望蘋果如何進行排序?他希望我們比較什麼特徵?
- 在那樣的環境中,“小於”,“等於”和“大於”指的是什麼意思?
也可以使用多個特徵,這個後面我們會講。
例1:通過重量排序蘋果
在第一個例子中,我們將通過重量對蘋果排序。只需要一行程式碼。
Collections.sort(apples);
例4
上面的程式碼行可以為我們做到所有的排序工作,只要我們事先定義好如何對蘋果進行排序(這就需要多行程式碼了)。
讓我們開始寫蘋果類吧。
public class Apple implements Comparable { private String variety; private Color color; private int weight; @Override public int compareTo(Apple other) { if (this.weight < other.weight) { return -1; } if (this.weight == other.weight) { return 0; } return 1; } }
例5
這是Apple類的第一個版本。由於我們使用的是compareTo方法,並且正在排序蘋果,所以我實現了Comparable介面。在這第一個版本中,我們通過重量比較物件。在我們的compareTo()方法中,我們寫一個if條件,說明如果這個蘋果的重量小於其他的蘋果,那麼返回一個負數,為了保持簡單,我們假定它為-1。請記住,這意味著這個蘋果輕於Apple ‘other’。在第二個if語句中,我們要說明,如果蘋果重量相等,那麼返回一個0。當然,如果這個蘋果既不是更輕,又不是一樣重,那就只能比其他蘋果更重了。在這種情況下,我們返回一個正數,假定為1。
例2:通過多個特徵排序蘋果
正如我前面提到的,我們還可以使用compareTo()比較多個特徵。比方說,我們第一通過品種排序蘋果,但如果兩個蘋果是同一品種,那麼我們就按顏色排序。最後,如果這兩個特性相同,那麼我們將按重量排序。雖然我們可以手動實現這件事,就像我在最後一個例子中做的那樣,但是其實可以用一種簡潔得多的方式實現。一般來說,最好是重用現有的程式碼,而不是自己寫。我們可以在Integer、String和列舉類中使用compareTo方法來比較值。由於我們沒有使用Integer物件,用了int,所以我們不得不使用來自於Integer包裝器類的一個靜態的helper方法來比較兩個值。
public class Apple implements Comparable { private String variety; private Color color; private int weight; @Override public int compareTo(Apple other) { int result = this.variety.compareTo(other.variety); if (result != 0) { return result; } if (result == 0) { result = this.color.compareTo(other.color); } if (result != 0) { return result; } if (result == 0) { result = Integer.compare(this.weight, other.weight); } return result; } }
例6
在例6中,我們比較了客戶指定的蘋果的第一特性,它們的品種。如果compareTo()呼叫的結果為非零,那麼我們返回值。否則,我們呼叫另一個compareTo()直到得到一個非零值,或者直到已經比較完這三個特徵。儘管此程式碼可以工作,但它不是最有效或乾淨的解決方案。在例3中,我們重構我們的程式碼,使其更簡單。
@Override public int compareTo(Apple other) { int result = this.variety.compareTo(other.variety); if (result == 0) { result = this.color.compareTo(other.color); } if (result == 0) { result = Integer.compare(this.weight, other.weight); } return result; }
例7
正如你所看到的,這大大減少了程式碼,並且每一次比較只要一行程式碼。如果一個compareTo()呼叫的結果是零,那麼我們就轉移到下一個相同if語句的比較中。順便說一句,這是成為Clean Coder的一個很好的例子。通常情況下,你不需要立即寫出乾淨的程式碼;你可以從一個粗略的想法開始,使其可以工作,然後不斷改進,直到你儘可能得讓它乾淨就可以了。
Comparable,hashCode以及Equals
你可能會注意到compareTo()看起來有點像hashCode()和equals()方法。但是,它們有一個重要的區別。對於hashCode()和equals()方法,比較個體屬性的順序不影響返回的值,但是,在compareTo()中,通過你比較物件的順序來定義物件的順序。
結論
在結論中我只想強調Comparable介面是多麼的重要。它既用於java.util.Arrays,也用於java.util.Collections實用程式類,來排序元素和搜尋排序集合中的元素。使用TreeSet和Tree Map,就更簡單了——想要它們會自動排序必須實現Comparable介面的元素。
譯文連結:http://www.codeceo.com/article/java-comparable-5-minutes.html
英文原文:Java Comparable Interface in Five Minutes
翻譯作者:碼農網 – 小峰
[ 轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊。]
相關文章
- 5分鐘搞定OKR工作法OKR
- 5分鐘搞定Promise控制併發Promise
- Java Comparable 和 Comparator 介面詳解Java
- 【JAVA語法】 -- 方便的Comparable介面Java
- 使用 HertzBeat 5分鐘搞定 SpringBoot2 監控告警Spring Boot
- 十分鐘搞定 GradleGradle
- 10分鐘搞定 Java 併發佇列好嗎?好的Java佇列
- JAVA中的Comparable介面和自定義比較器Java
- 5分鐘搞定 服務端 本地開發 遠端執行服務端
- 5分鐘,輕鬆搞定Oracle資料庫等保測評Oracle資料庫
- 10 分鐘搞定 Golang 結構體Golang結構體
- 五分鐘搞定Docker安裝ElasticSearchDockerElasticsearch
- java之5分鐘插入千萬條資料Java
- 三分鐘搞定 Springboot 和Swagger 整合Spring BootSwagger
- 10分鐘搞定Mysql主從部署配置MySql
- JDK原始碼閱讀-Comparable介面JDK原始碼
- 3 分鐘搞定 Vue 2.0 服務端渲染Vue服務端
- 30分鐘帶你搞定Dokcer部署Kafka叢集Kafka
- 三分鐘搞定nodejs基礎API之PathNodeJSAPI
- 5分鐘入門AWK
- 5分鐘學會 gRPCRPC
- 5分鐘實現呼叫ChatGPT介面API實現多輪問答ChatGPTAPI
- 【入門教程】5分鐘教你快速學會整合Java springboot ~JavaSpring Boot
- Java基礎系列-Comparable和ComparatorJava
- Java 中 Comparable 和 Comparator 比較Java
- 一分鐘搞定EVE-NG怎麼安裝
- 【設計模式】三、單例模式(10分鐘深度搞定)設計模式單例
- 2分鐘讀懂javaJava
- 透過這個神仙工具,耗時半天的簽字審批現在5分鐘搞定!
- 從java內建類和自定義類比較Comparable介面和Comparator介面實現排序的不同Java排序
- 5分鐘快速瞭解 RedisRedis
- 5分鐘 Pipenv 上手指南
- 5分鐘掌握JavaScript小技巧JavaScript
- 5分鐘談前端面試前端面試
- 5分鐘安裝docker教程Docker
- Java智慧之Spring AI:5分鐘打造智慧聊天模型的利器JavaSpringAI模型
- 五分鐘搞定Bash功能與使用技巧,運維速收!運維
- 伺服器穩定性的測試方法,1分鐘搞定伺服器