5 分鐘搞定 Java Comparable 介面
這篇文章是免費Java 8 課程中關於Clean Code原則的一部分。
在這篇文章中,我們要聊一聊介面。
還有一個不錯的影片可以點。
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例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中,我們重構我們的程式碼,使其更簡單。
@Overridepublic 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介面的元素。
譯文連結:
英文原文:
翻譯作者: – 小峰
[ 轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊。]
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4479/viewspace-2809438/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 5分鐘搞定開機引導介面
- 5分鐘搞定Promise控制併發Promise
- 5分鐘搞定OKR工作法OKR
- java中的Comparable介面Java
- 【JAVA語法】 -- 方便的Comparable介面Java
- Java Comparable 和 Comparator 介面詳解Java
- 十分鐘搞定 GradleGradle
- Java Comparable排序介面和Comparator比較器介面Java排序
- 10分鐘搞定 Java 併發佇列好嗎?好的Java佇列
- 5分鐘搞定 服務端 本地開發 遠端執行服務端
- 使用 HertzBeat 5分鐘搞定 SpringBoot2 監控告警Spring Boot
- 5分鐘,輕鬆搞定Oracle資料庫等保測評Oracle資料庫
- 5分鐘 搞定UIButton的文字與圖片的佈局UI
- 五分鐘搞定Docker安裝ElasticSearchDockerElasticsearch
- Java中Comparable和Comparator介面區別分析Java
- 十分鐘搞定CSS選擇器CSS
- 10分鐘搞定Mysql主從部署配置MySql
- java之5分鐘插入千萬條資料Java
- JAVA中的Comparable介面和自定義比較器Java
- 十分鐘搞定酷炫動畫,萬聖節驚悚的聊天介面動畫
- 3 分鐘搞定 Vue 2.0 服務端渲染Vue服務端
- QardioArm智慧血壓計:一分鐘搞定!
- 快速SQL TUNING——1分鐘搞定超慢SQLSQL
- 30分鐘帶你搞定Dokcer部署Kafka叢集Kafka
- 5分鐘入門AWK
- QUnit5分鐘教程
- JDK原始碼閱讀-Comparable介面JDK原始碼
- Comparable介面的實現和使用
- 5分鐘實現呼叫ChatGPT介面API實現多輪問答ChatGPTAPI
- 三分鐘搞定nodejs基礎API之PathNodeJSAPI
- 一分鐘搞定EVE-NG怎麼安裝
- 【設計模式】三、單例模式(10分鐘深度搞定)設計模式單例
- 一分鐘搞定AlloyTouch圖片輪播元件元件
- Java Comparable 與 ComparatorJava
- 5分鐘談前端面試前端面試
- 5分鐘安裝docker教程Docker
- 5分鐘快速瞭解 RedisRedis
- 5分鐘 Pipenv 上手指南