搜尋
首頁Javajava教程Java 中的比較器是如何運作的?

¿Cómo funciona Comparator en Java?

介紹

有時在做專案時需要對某種類型的物件集合進行排序,為此你可能會認為有必要實作我們自己的排序演算法,但這有點不必要,儘管了解一下也沒什麼壞處他們如何運作。例如,如果您有一個整數數組,則可以使用Arrays.sort() 方法,該方法接受基元數組並按升序對其進行排序,從而利用無需將結果分配給新變量,因為該方法修改了原始數組。

int[] numbers = {9, 8, 5, 3, 1, 2, 4, 6, 7};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));

// Output
[1, 2, 3, 4, 5, 6, 7, 8, 9]

當您有自訂物件的集合(例如Movie 類型的記錄)時,這也適用,但如果我們看到Arrays.sort() 方法,它不接受這種類型的物件數組,因此它必須使用sort() 方法接受T 類型的物件和Comparator 類型的物件作為參數超級T>這是一個函數式介面。這個介面非常重要,因為 Java 中的許多其他方法都使用它以自訂方式比較物件。例如,List 物件的 Collections.sort() 方法或 sort() 方法,甚至 Streams 也接受 Comparator 來對元素進行排序。

什麼是比較器?

函數式介面Comparator(函數式它可以寫成lambda表達式)是一個允許你比較兩個T類型物件的接口,因此它用於比較整數、字串、自訂物件等此介面有幾個靜態和預設方法,但重要的是compare() 方法,它是比較兩個物件必須實作的方法。 Compare() 接收兩個 T 類型的物件並傳回一個整數。方法簽名如下:

int compare(T o1, T o2);

如果o1小於o2,則該方法傳回負數;如果相等,則傳回零;如果o1大於o2,則方法傳回正數,通常分別回傳-1、0或1。

一個物件小於、等於或大於另一個物件意味著什麼?

讓我們分析一下compare()方法傳回的內容,因為物件的排序取決於此,重要的是要考慮該方法返回的含義是相對的,也就是說,如果您想要升序或降序排列。這取決於具體情況以及如何實施。讓我們為每個範例考慮以下記錄

int[] numbers = {9, 8, 5, 3, 1, 2, 4, 6, 7};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));

// Output
[1, 2, 3, 4, 5, 6, 7, 8, 9]
  • 如果第一個參數小於第二個參數,則傳回負數。例如,要按發行年份對電影進行排序,當電影 a 小於電影 b 時,可以回傳 -1:
int compare(T o1, T o2);
  • 如果第一個參數大於第二個參數,則傳回正數。例如,要按預算對電影進行排序,當電影 a 大於電影 b 時,可以返回 1:
public record Movie(
        String name,
        List<string> actors,
        int budget,
        int year
) {
}
</string>
  • 如果第一個參數等於第二個參數,則傳回零。例如,要按演員數量對電影進行排序,當電影 a 等於電影 b 時,可以返回 0:
// a  -1
a.year()  -1

使用比較器

假設我們在 List 類型的物件中有以下影片:

// a > b -> 1
a.budget() > b.budget() -> 1

如果您想按發行年份升序排列電影,您可以建立一個 Comparator 類型的物件並重寫compare()方法,然後將此物件傳遞給清單的sort()方法:

// a == b -> 0
a.actors().size() == b.actors().size() -> 0

它也可以在 sort() 方法中實作為匿名類別:

Movie movie1 = new Movie("The Godfather", Arrays.asList("Marlon Brando", "Al Pacino"), 6000000, 1972);
Movie movie2 = new Movie("The Godfather: Part II", Arrays.asList("Al Pacino", "Robert De Niro"), 13000000, 1974);
Movie movie3 = new Movie("The Shawshank Redemption", Arrays.asList("Tim Robbins", "Morgan Freeman"), 25000000, 1994);
Movie movie4 = new Movie("The Dark Knight", Arrays.asList("Christian Bale", "Heath Ledger"), 185000000, 2008);

List<movie> movies = Arrays.asList(movie1, movie2, movie3, movie4);
</movie>

或更簡潔地直接在 sort() 方法中使用 lambda 表達式:

Comparator<movie> comparatorByYear = new Comparator<movie>() {
    @Override
    public int compare(Movie o1, Movie o2) {
        return o1.year() - o2.year();
    }
};

movies.sort(comparatorByYear);
</movie></movie>

任何這些實作都會按發布年份對清單進行升序排序。如果要按降序排序,可以更改 lambda 表達式中參數的順序,或在減法中加入負號:

movies.sort(new Comparator<movie>() {
    @Override
    public int compare(Movie o1, Movie o2) {
        return o1.year() - o2.year();
    }
});
</movie>

如何對自訂物件清單進行排序的一些其他範例是:

  • 依演員數量升序排列電影(從少到多):
movies.sort((p1, p2) -> p1.year() - p2.year());
  • 依預算降序對電影進行排序(從最高預算到最低預算):
movies.sort((p1, p2) -> p2.year() - p1.year());
// o
movies.sort((p1, p2) -> - (p1.year() - p2.year()));
  • 依名稱以升序對電影進行排序:
movies.sort((p1, p2) -> p1.actors().size() - p2.actors().size());

在其他範例中,我們可能會遇到需要依降序對整數清單進行排序的情況,

movies.sort((p1, p2) -> p2.budget() - p1.budget());
// o 
movies.sort((p1, p2) -> - (p1.budget() - p2.budget()));

為此,您也可以使用靜態方法 Comparator.reverseOrder() 傳回一個按降序對元素進行排序的比較器,以及使用 Comparator.naturalOrder() 按升序對元素進行排序。

int[] numbers = {9, 8, 5, 3, 1, 2, 4, 6, 7};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));

// Output
[1, 2, 3, 4, 5, 6, 7, 8, 9]

使用 Integer.compare()

在Java 中已經有一些方法允許我們以有效的方式執行這種類型的比較,例如Integer.compare() ,它比較兩個整數,如果第一個參數小於第二個參數零,則傳回負數如果第一個參數大於第二個參數,則相等且為正數。如果我們分析這個方法的工作原理,我們可以看到它與上面解釋的類似,並且傳回的正是Comparator介面的compare()方法所需要的。 Integer.compare() 的實作如下:

int compare(T o1, T o2);

因此,如果您想按發行年份升序對影片進行排序,可以使用 Integer.compare():

public record Movie(
        String name,
        List<string> actors,
        int budget,
        int year
) {
}
</string>

使用參考方法

有時可以使用引用方法來執行與先前不同的比較,例如,按升序對整數清單進行排序:

// a  -1
a.year()  -1

Integer 不是唯一具有compareTo() 方法的類,例如String 有一個compareTo() 方法,可以按字典順序比較兩個字串,因此它可以用於對字串列表進行排序,甚至可以將CharSequence 與其一起使用Compare() 方法(技術上表示字元序列)。

// a > b -> 1
a.budget() > b.budget() -> 1

回到電影的例子,如果你想按照上映年份升序對電影進行排序,可以使用compareingInt()方法作為參考方法:

// a == b -> 0
a.actors().size() == b.actors().size() -> 0

或根據 String 類型屬性進行比較,在本例中為電影名稱:

Movie movie1 = new Movie("The Godfather", Arrays.asList("Marlon Brando", "Al Pacino"), 6000000, 1972);
Movie movie2 = new Movie("The Godfather: Part II", Arrays.asList("Al Pacino", "Robert De Niro"), 13000000, 1974);
Movie movie3 = new Movie("The Shawshank Redemption", Arrays.asList("Tim Robbins", "Morgan Freeman"), 25000000, 1994);
Movie movie4 = new Movie("The Dark Knight", Arrays.asList("Christian Bale", "Heath Ledger"), 185000000, 2008);

List<movie> movies = Arrays.asList(movie1, movie2, movie3, movie4);
</movie>

按多個屬性排序

有時你可能需要按多個屬性對物件清單進行排序,例如,如果你想按發行年份升序對電影進行排序,按預算降序排序,你可以使用thenComparing() 方法,該方法接收一個比較器,負責按多個屬性排序。例如,如果有兩部電影a和b,上映年份相同,則按預算排序。

Comparator<movie> comparatorByYear = new Comparator<movie>() {
    @Override
    public int compare(Movie o1, Movie o2) {
        return o1.year() - o2.year();
    }
};

movies.sort(comparatorByYear);
</movie></movie>

結論

比較器在Java中很多時候都很有用,因為它們可以讓你以個人化的方式比較對象,不僅如此,它們還可以用在許多Java集合方法中,甚至可以有多個比較器來排序以不同的方式。無論哪種方式,您都可以查閱 IDE 中的 Comparator 文件或官方 Java 文檔,以了解可以使用哪些方法以及如何實作它們。

以上是Java 中的比較器是如何運作的?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
平台獨立性如何使企業級的Java應用程序受益?平台獨立性如何使企業級的Java應用程序受益?May 03, 2025 am 12:23 AM

Java在企業級應用中被廣泛使用是因為其平台獨立性。 1)平台獨立性通過Java虛擬機(JVM)實現,使代碼可在任何支持Java的平台上運行。 2)它簡化了跨平台部署和開發流程,提供了更大的靈活性和擴展性。 3)然而,需注意性能差異和第三方庫兼容性,並採用最佳實踐如使用純Java代碼和跨平台測試。

考慮到平台獨立性,Java在物聯網(物聯網)設備的開發中扮演什麼角色?考慮到平台獨立性,Java在物聯網(物聯網)設備的開發中扮演什麼角色?May 03, 2025 am 12:22 AM

JavaplaysigantroleiniotduetoitsplatFormentence.1)itallowscodeTobewrittenOnCeandrunonVariousDevices.2)Java'secosystemprovidesuseusefidesusefidesulylibrariesforiot.3)

描述一個方案,您在Java中遇到了一個特定於平台的問題以及如何解決。描述一個方案,您在Java中遇到了一個特定於平台的問題以及如何解決。May 03, 2025 am 12:21 AM

ThesolutiontohandlefilepathsacrossWindowsandLinuxinJavaistousePaths.get()fromthejava.nio.filepackage.1)UsePaths.get()withSystem.getProperty("user.dir")andtherelativepathtoconstructthefilepath.2)ConverttheresultingPathobjecttoaFileobjectifne

Java平台獨立對開發人員有什麼好處?Java平台獨立對開發人員有什麼好處?May 03, 2025 am 12:15 AM

Java'splatFormIndenceistificantBecapeitAllowSitallowsDevelostWriTecoDeonCeandRunitonAnyPlatFormwithAjvm.this“ writeonce,runanywhere”(era)櫥櫃櫥櫃:1)交叉plat formcomplibility cross-platformcombiblesible,enablingDeploymentMentMentMentMentAcrAptAprospOspOspOssCrossDifferentoSswithOssuse; 2)

將Java用於需要在不同服務器上運行的Web應用程序的優點是什麼?將Java用於需要在不同服務器上運行的Web應用程序的優點是什麼?May 03, 2025 am 12:13 AM

Java適合開發跨服務器web應用。 1)Java的“一次編寫,到處運行”哲學使其代碼可在任何支持JVM的平台上運行。 2)Java擁有豐富的生態系統,包括Spring和Hibernate等工具,簡化開發過程。 3)Java在性能和安全性方面表現出色,提供高效的內存管理和強大的安全保障。

JVM如何促進Java的'寫作一次,在任何地方運行”(WORA)功能?JVM如何促進Java的'寫作一次,在任何地方運行”(WORA)功能?May 02, 2025 am 12:25 AM

JVM通過字節碼解釋、平台無關的API和動態類加載實現Java的WORA特性:1.字節碼被解釋為機器碼,確保跨平台運行;2.標準API抽像操作系統差異;3.類在運行時動態加載,保證一致性。

Java的較新版本如何解決平台特定問題?Java的較新版本如何解決平台特定問題?May 02, 2025 am 12:18 AM

Java的最新版本通過JVM優化、標準庫改進和第三方庫支持有效解決平台特定問題。 1)JVM優化,如Java11的ZGC提升了垃圾回收性能。 2)標準庫改進,如Java9的模塊系統減少平台相關問題。 3)第三方庫提供平台優化版本,如OpenCV。

說明JVM執行的字節碼驗證的過程。說明JVM執行的字節碼驗證的過程。May 02, 2025 am 12:18 AM

JVM的字節碼驗證過程包括四個關鍵步驟:1)檢查類文件格式是否符合規範,2)驗證字節碼指令的有效性和正確性,3)進行數據流分析確保類型安全,4)平衡驗證的徹底性與性能。通過這些步驟,JVM確保只有安全、正確的字節碼被執行,從而保護程序的完整性和安全性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!