亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

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

Java 中的比較器是如何運作的?

Nov 05, 2024 pm 04:52 PM

?Cómo funciona Comparator en Java?

介紹

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

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() 方法,它不接受這種類型的物件數(shù)組,因此它必須使用sort() 方法接受T 類型的物件和Comparator 類型的物件作為參數(shù)超級T>這是一個函數(shù)式介面。這個介面非常重要,因為 Java 中的許多其他方法都使用它以自訂方式比較物件。例如,List 物件的 Collections.sort() 方法或 sort() 方法,甚至 Streams 也接受 Comparator 來對元素進行排序。

什麼是比較器?

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

int compare(T o1, T o2);

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

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

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

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

使用比較器

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

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

如果您想按發(fā)行年份升序排列電影,您可以建立一個 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);

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

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

movies.sort(comparatorByYear);

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

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

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

  • 依演員數(shù)量升序排列電影(從少到多):
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());

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

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

為此,您也可以使用靜態(tài)方法 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 中已經(jīng)有一些方法允許我們以有效的方式執(zhí)行這種類型的比較,例如Integer.compare() ,它比較兩個整數(shù),如果第一個參數(shù)小於第二個參數(shù)零,則傳回負數(shù)如果第一個參數(shù)大於第二個參數(shù),則相等且為正數(shù)。如果我們分析這個方法的工作原理,我們可以看到它與上面解釋的類似,並且傳回的正是Comparator介面的compare()方法所需要的。 Integer.compare() 的實作如下:

int compare(T o1, T o2);

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

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

使用參考方法

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

// a < b -> -1
a.year() < b.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

或根據(jù) 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);

按多個屬性排序

有時你可能需要按多個屬性對物件清單進行排序,例如,如果你想按發(fā)行年份升序對電影進行排序,按預算降序排序,你可以使用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);

結論

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

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

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發(fā)現(xiàn)涉嫌抄襲或侵權的內(nèi)容,請聯(lián)絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

記事本++7.3.1

記事本++7.3.1

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

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

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

Java中可呼叫和可運行的差異 Java中可呼叫和可運行的差異 Jul 04, 2025 am 02:50 AM

Callable和Runnable在Java中主要有三點區(qū)別。第一,Callable的call()方法可以返回結果,適合需要返回值的任務,如Callable;而Runnable的run()方法無返回值,適用於無需返回的任務,如日誌記錄。第二,Callable允許拋出checked異常,便於錯誤傳遞;而Runnable必須在內(nèi)部處理異常。第三,Runnable可直接傳給Thread或ExecutorService,而Callable只能提交給ExecutorService,並返回Future對像以

現(xiàn)代爪哇的異步編程技術 現(xiàn)代爪哇的異步編程技術 Jul 07, 2025 am 02:24 AM

Java支持異步編程的方式包括使用CompletableFuture、響應式流(如ProjectReactor)以及Java19 中的虛擬線程。 1.CompletableFuture通過鍊式調(diào)用提升代碼可讀性和維護性,支持任務編排和異常處理;2.ProjectReactor提供Mono和Flux類型實現(xiàn)響應式編程,具備背壓機制和豐富的操作符;3.虛擬線程減少並發(fā)成本,適用於I/O密集型任務,與傳統(tǒng)平臺線程相比更輕量且易於擴展。每種方式均有適用場景,應根據(jù)需求選擇合適工具並避免混合模型以保持簡潔性

了解Java Nio及其優(yōu)勢 了解Java Nio及其優(yōu)勢 Jul 08, 2025 am 02:55 AM

JavaNIO是Java1.4引入的新型IOAPI,1)面向緩衝區(qū)和通道,2)包含Buffer、Channel和Selector核心組件,3)支持非阻塞模式,4)相比傳統(tǒng)IO更高效處理並發(fā)連接。其優(yōu)勢體現(xiàn)在:1)非阻塞IO減少線程開銷,2)Buffer提升數(shù)據(jù)傳輸效率,3)Selector實現(xiàn)多路復用,4)內(nèi)存映射加快文件讀寫。使用時需注意:1)Buffer的flip/clear操作易混淆,2)非阻塞下需手動處理不完整數(shù)據(jù),3)Selector註冊需及時取消,4)NIO並非適用於所有場景。

在Java中使用枚舉的最佳實踐 在Java中使用枚舉的最佳實踐 Jul 07, 2025 am 02:35 AM

在Java中,枚舉(enum)適合表示固定常量集合,最佳實踐包括:1.用enum表示固定狀態(tài)或選項,提升類型安全和可讀性;2.為枚舉添加屬性和方法以增強靈活性,如定義字段、構造函數(shù)、輔助方法等;3.使用EnumMap和EnumSet提高性能和類型安全性,因其基於數(shù)組實現(xiàn)更高效;4.避免濫用enum,如動態(tài)值、頻繁變更或複雜邏輯場景應使用其他方式替代。正確使用enum能提升代碼質量並減少錯誤,但需注意其適用邊界。

Java Classloader在內(nèi)部如何工作 Java Classloader在內(nèi)部如何工作 Jul 06, 2025 am 02:53 AM

Java的類加載機制通過ClassLoader實現(xiàn),其核心工作流程分為加載、鏈接和初始化三個階段。加載階段由ClassLoader動態(tài)讀取類的字節(jié)碼並創(chuàng)建Class對象;鏈接包括驗證類的正確性、為靜態(tài)變量分配內(nèi)存及解析符號引用;初始化則執(zhí)行靜態(tài)代碼塊和靜態(tài)變量賦值。類加載採用雙親委派模型,優(yōu)先委託父類加載器查找類,依次嘗試Bootstrap、Extension和ApplicationClassLoader,確保核心類庫安全且避免重複加載。開發(fā)者可自定義ClassLoader,如URLClassL

探索Java中不同的同步機制 探索Java中不同的同步機制 Jul 04, 2025 am 02:53 AM

Javaprovidesmultiplesynchronizationtoolsforthreadsafety.1.synchronizedblocksensuremutualexclusionbylockingmethodsorspecificcodesections.2.ReentrantLockoffersadvancedcontrol,includingtryLockandfairnesspolicies.3.Conditionvariablesallowthreadstowaitfor

有效處理常見的Java例外 有效處理常見的Java例外 Jul 05, 2025 am 02:35 AM

Java異常處理的關鍵在於區(qū)分checked和unchecked異常並合理使用try-catch、finally及日誌記錄。 1.checked異常如IOException需強制處理,適用於可預期的外部問題;2.unchecked異常如NullPointerException通常由程序邏輯錯誤引起,屬於運行時錯誤;3.捕獲異常時應具體明確,避免籠統(tǒng)捕獲Exception;4.推薦使用try-with-resources自動關閉資源,減少手動清理代碼;5.異常處理中應結合日誌框架記錄詳細信息,便於後

Hashmap在Java內(nèi)部如何工作? Hashmap在Java內(nèi)部如何工作? Jul 15, 2025 am 03:10 AM

HashMap在Java中通過哈希表實現(xiàn)鍵值對存儲,其核心在於快速定位數(shù)據(jù)位置。 1.首先使用鍵的hashCode()方法生成哈希值,並通過位運算轉換為數(shù)組索引;2.不同對象可能產(chǎn)生相同哈希值,導致衝突,此時以鍊錶形式掛載節(jié)點,JDK8後鍊錶過長(默認長度8)則轉為紅黑樹提升效率;3.使用自定義類作鍵時必須重寫equals()和hashCode()方法;4.HashMap動態(tài)擴容,當元素數(shù)超過容量乘以負載因子(默認0.75)時,擴容並重新哈希;5.HashMap非線程安全,多線程下應使用Concu

See all articles