欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java?中的排序Comparable?與?Comparator?的使用與區(qū)別對(duì)比解析

 更新時(shí)間:2025年09月15日 11:46:47   作者:你我約定有三  
本文給大家介紹Java中的排序Comparable與Comparator的使用與區(qū)別對(duì)比,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

1. 背景

在 Java 中,如果我們希望自定義類能夠進(jìn)行排序(例如在集合、數(shù)組中排序),就需要定義對(duì)象的比較規(guī)則。

Java 提供了兩種方式:

  • Comparable<T> 接口 → 在類內(nèi)部實(shí)現(xiàn),定義對(duì)象的“自然順序”。
  • Comparator<T> 接口 → 在類外部定義比較器,可以靈活指定不同的排序規(guī)則。

2.Comparable接口

Java 中很多常用類都實(shí)現(xiàn)了 Comparable 接口,例如 String、Integer。

public class CompareToDemo {
    public static void main(String[] args) {
        // String 按字典序比較
        System.out.println("apple".compareTo("banana")); // -1
        System.out.println("dog".compareTo("dog"));      // 0
        System.out.println("zoo".compareTo("apple"));    // 正數(shù)
        // Integer 按數(shù)值大小比較
        Integer a = 10, b = 20;
        System.out.println(a.compareTo(b)); // -1
        System.out.println(b.compareTo(a)); // 1
        System.out.println(a.compareTo(10));// 0
    }
}

2.1 定義

public interface Comparable<T> {
    int compareTo(T o);
}

2.2 返回值含義

  • 負(fù)數(shù):當(dāng)前對(duì)象 < 參數(shù)對(duì)象
  • 0:當(dāng)前對(duì)象 == 參數(shù)對(duì)象
  • 正數(shù):當(dāng)前對(duì)象 > 參數(shù)對(duì)象

2.3 使用場(chǎng)景

當(dāng)一個(gè)類本身就有固定的“自然排序規(guī)則”,可以直接實(shí)現(xiàn) Comparable

3.Comparator接口

3.1 定義

public interface Comparator<T> {
    int compare(T o1, T o2);
}

3.2 返回值含義

Comparable 相同:

  • 負(fù)數(shù) → o1 < o2
  • 0 → o1 == o2
  • 正數(shù) → o1 > o2

3.3 使用場(chǎng)景

當(dāng)我們不想修改類本身,或者需要定義多種排序規(guī)則時(shí),使用 Comparator 更靈活。

4.ComparablevsComparator區(qū)別表

特性ComparableComparator
方法int compareTo(T o)int compare(T o1, T o2)
定義位置內(nèi)部(實(shí)現(xiàn)接口)外部(單獨(dú)寫比較器)
排序規(guī)則數(shù)量一種(自然順序)多種(可定義多個(gè) Comparator)
修改類代碼需求需要修改類本身不需要修改類本身
常見(jiàn)使用場(chǎng)景Collections.sort(list)Collections.sort(list, comparator)

5. Comparable 與 Comparator的使用示例:對(duì)List<Student>按age排序

5.1 使用Comparable

class Student implements Comparable<Student> {
    private String name;
    private int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // 定義“自然順序”:按年齡升序
    @Override
    public int compareTo(Student other) {
        return Integer.compare(this.age, other.age);
    }
    @Override
    public String toString() {
        return name + "(" + age + ")";
    }
}
public class ComparableDemo {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();
        list.add(new Student("Alice", 22));
        list.add(new Student("Bob", 18));
        list.add(new Student("Charlie", 20));
        // 使用 Comparable 定義的 compareTo 方法排序
        Collections.sort(list);
        System.out.println(list); 
        // 輸出: [Bob(18), Charlie(20), Alice(22)]
    }
}

5.2 使用Comparator

如果我們不想修改 Student 類,或者想要不同的排序規(guī)則,可以使用 Comparator。

方式一:匿名內(nèi)部類

Collections.sort(list, new Comparator<Student>() {
    @Override
    public int compare(Student s1, Student s2) {
        return Integer.compare(s1.getAge(), s2.getAge());
    }
});

方式二:Lambda 表達(dá)式(Java 8+推薦)

list.sort((s1, s2) -> Integer.compare(s1.getAge(), s2.getAge()));

方式三:方法引用(更簡(jiǎn)潔)

list.sort(Comparator.comparing(Student::getAge));

?? 輸出結(jié)果同樣是:

[Bob(18), Charlie(20), Alice(22)]

6. 多條件排序(進(jìn)階)

6.1使用Comparator實(shí)現(xiàn)多條件排序

使Comparator 時(shí),可以輕松實(shí)現(xiàn)多條件排序。

例如:先按年齡升序,再按名字字母序升序

//方式一、方法引用 + 鏈?zhǔn)?Comparator
list.sort(
    Comparator.comparing(Student::getAge)
              .thenComparing(Student::getName)
);
//方式二、匿名內(nèi)部類寫法
list.sort(new Comparator<Student>() {
    @Override
    public int compare(Student s1, Student s2) {
        // 先按年齡排序
        int result = Integer.compare(s1.getAge(), s2.getAge());
        // 如果年齡相同,則按姓名排序
        if (result == 0) {
            result = s1.getName().compareTo(s2.getName());
        }
        return result;
    }
});
//方式三、Lambda 表達(dá)式寫法(Java 8+ 推薦)
list.sort((s1, s2) -> {
    int result = Integer.compare(s1.getAge(), s2.getAge());
    if (result == 0) {
        result = s1.getName().compareTo(s2.getName());
    }
    return result;
});

6.2 那是不是不能使用Comparable完成多條件呢?

1??Comparable的特點(diǎn)

  • Comparable自然排序(對(duì)象自己規(guī)定的排序規(guī)則)。
  • 一個(gè)類 只能實(shí)現(xiàn)一次 compareTo 方法,也就是說(shuō)只能有一種排序邏輯。
  • 例子:
public class Student implements Comparable<Student> {
    private int age;
    private String name;
    @Override
    public int compareTo(Student other) {
        // 先按年齡,再按姓名
        int result = Integer.compare(this.age, other.age);
        if (result == 0) {
            result = this.name.compareTo(other.name);
        }
        return result;
    }
}

?? 這樣就能實(shí)現(xiàn) 多條件排序,但限制是 Student 這個(gè)類就被固定死了,始終用這一套排序規(guī)則(先按年齡升序,再按名字字母序升序),如果后續(xù)想先按照名字字母就要改這個(gè)compareTo方法。

2??Comparator的特點(diǎn)

  • Comparator外部比較器,不修改實(shí)體類本身。
  • 可以定義多個(gè)不同的排序規(guī)則,根據(jù)需要隨時(shí)切換。
  • 例子(用的上面使用Comparator 實(shí)現(xiàn)多條件排序的方式一):
Comparator<Student> byAgeThenName = 
    Comparator.comparing(Student::getAge)
              .thenComparing(Student::getName);
Comparator<Student> byNameThenAge = 
    Comparator.comparing(Student::getName)
              .thenComparing(Student::getAge);

?? 這樣一個(gè)類(Student)就可以有 多種排序方式,靈活性更高。

3?? 多條件的對(duì)比

  • Comparable:類內(nèi)部定義,固定一種排序邏輯(可以寫多條件,但只能有這一種)。
  • Comparator:類外部定義,可以有多種排序邏輯,靈活組合,推薦用于多條件排序。

?? 這樣就能實(shí)現(xiàn) 多條件排序,但限制是 Student 這個(gè)類就被固定死了,始終用這一套排序規(guī)則。

? 多條件排序,Comparable 也能實(shí)現(xiàn)(在 compareTo 里寫多條件邏輯)。
? 但是 Comparable 只能有這一種排序方式,靈活性差。
?? 真正業(yè)務(wù)里,一般 多條件排序都會(huì)用 Comparator。

7. 總結(jié)

  • Comparable:讓類具備自然排序能力,適合“唯一固定規(guī)則”的場(chǎng)景。
  • Comparator:外部比較器,適合需要定義多種排序規(guī)則的場(chǎng)景。
    • 對(duì)于 List<Student>
    • 如果 Student 類實(shí)現(xiàn)了 Comparable,直接用 Collections.sort(list)
    • 如果不想改 Student 類,可以用 Comparator 方式排序。
  • 推薦使用 Comparator.comparing(...) + Lambda/方法引用,更簡(jiǎn)潔靈活。

到此這篇關(guān)于java--Java 中的排序:Comparable 與 Comparator 的使用與區(qū)別的文章就介紹到這了,更多相關(guān)java Comparable 與 Comparator使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Java中的Lambda表達(dá)式

    詳解Java中的Lambda表達(dá)式

    這篇文章主要介紹了Java中的Lambda表達(dá)式的的相關(guān)資料,文中講解非常詳細(xì),示例代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • Java API學(xué)習(xí)教程之正則表達(dá)式詳解

    Java API學(xué)習(xí)教程之正則表達(dá)式詳解

    正則表達(dá)式的強(qiáng)大眾所周知,它令程序員的頭痛程度也數(shù)一數(shù)二的。下面這篇文章主要給大家介紹了關(guān)于Java API學(xué)習(xí)教程之正則表達(dá)式的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-07-07
  • Java全局異常處理器實(shí)現(xiàn)過(guò)程解析

    Java全局異常處理器實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了Java全局異常處理器實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Spring中網(wǎng)絡(luò)請(qǐng)求客戶端WebClient的使用詳解

    Spring中網(wǎng)絡(luò)請(qǐng)求客戶端WebClient的使用詳解

    作為替代,Spring 官方已在 Spring 5 中引入了 WebClient 作為非阻塞式 Reactive HTTP 客戶端,本文將通過(guò)樣例演示如何使用 WebClient,希望對(duì)大家有所幫助
    2024-04-04
  • Java基于HttpClient實(shí)現(xiàn)RPC的示例

    Java基于HttpClient實(shí)現(xiàn)RPC的示例

    HttpClient可以實(shí)現(xiàn)使用Java代碼完成標(biāo)準(zhǔn)HTTP請(qǐng)求及響應(yīng)。本文主要介紹了Java基于HttpClient實(shí)現(xiàn)RPC,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 使用Spring boot標(biāo)記一個(gè)方法過(guò)時(shí)

    使用Spring boot標(biāo)記一個(gè)方法過(guò)時(shí)

    這篇文章主要介紹了使用Spring boot標(biāo)記一個(gè)方法過(guò)時(shí),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • 解析Oracle數(shù)據(jù)庫(kù)中的對(duì)象集合schema

    解析Oracle數(shù)據(jù)庫(kù)中的對(duì)象集合schema

    這篇文章主要介紹了Oracle數(shù)據(jù)庫(kù)中的對(duì)象集合schema,是Oracle數(shù)據(jù)庫(kù)入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-11-11
  • IDEA?Error:java:無(wú)效的源發(fā)行版:13的解決過(guò)程

    IDEA?Error:java:無(wú)效的源發(fā)行版:13的解決過(guò)程

    之前用idea運(yùn)行時(shí),也會(huì)出現(xiàn)這種情況,后面通過(guò)網(wǎng)上的資料解決了這個(gè)問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于IDEA?Error:java:無(wú)效的源發(fā)行版:13的解決過(guò)程,需要的朋友可以參考下
    2023-01-01
  • Java線程讓步_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java線程讓步_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    yield()的作用是讓步。它能讓當(dāng)前線程由“運(yùn)行狀態(tài)”進(jìn)入到“就緒狀態(tài)”,從而讓其它具有相同優(yōu)先級(jí)的等待線程獲取執(zhí)行權(quán)。下面通過(guò)本文給大家介紹Java線程讓步的相關(guān)知識(shí),需要的朋友參考下吧
    2017-05-05
  • VSCode?配置?Spring?Boot?項(xiàng)目開(kāi)發(fā)環(huán)境的全過(guò)程

    VSCode?配置?Spring?Boot?項(xiàng)目開(kāi)發(fā)環(huán)境的全過(guò)程

    兩三年前曾經(jīng)試過(guò)配置Java環(huán)境, 存在不少問(wèn)題作罷. 最近搜了下相關(guān)的文章, 感覺(jué)VSCode對(duì)Java項(xiàng)目的支持比三年前完善了不少. 今天實(shí)際配置了一下環(huán)境, 把自己常用的功能過(guò)了一遍, 基本能跑通開(kāi)發(fā)流程, 做個(gè)筆記,需要的朋友可以參考下
    2024-03-03

最新評(píng)論