亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java中比較器Comparable和Comparator超詳細(xì)解析

 更新時間:2025年06月18日 10:45:33   作者:小釗.  
Java中在進(jìn)行數(shù)據(jù)排序時,Comparable和Comparator必不可少會遇得到,這篇文章主要給大家介紹了關(guān)于Java中比較器Comparable和Comparator的相關(guān)資料,需要的朋友可以參考下

前言

在 Java 中,Comparable 和 Comparator 是用于對象排序的重要接口。它們提供了不同的排序方式,適用于不同的需求,同時在 Java 底層排序算法中發(fā)揮著關(guān)鍵作用。本文將從基礎(chǔ)概念、使用方法、排序?qū)崿F(xiàn)(包括升序、降序)、底層實現(xiàn)原理以及適用場景等方面進(jìn)行詳細(xì)解析。

一、 Comparable 和 Comparator 的基本概念

在 Java 中,排序通常用于 數(shù)組 和 集合(List),兩者的排序分別由 Arrays.sort() 和 Collections.sort() 進(jìn)行,而這兩個方法都依賴于 Comparable 和 Comparator。

1.1 Comparable 接口(自然排序)

  • Comparable 是一個 內(nèi)部比較器,表示對象本身支持排序規(guī)則。

  • 需要在類中實現(xiàn) compareTo() 方法,定義默認(rèn)的排序方式。

  • 適用于對象有唯一的自然排序方式,如 Integer、String、Double 等。

代碼示例(按照 age 升序排序):

class Person implements Comparable<Person> {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Person other) {
        return Integer.compare(this.age, other.age); // 按年齡升序
    }

    @Override
    public String toString() {
        return name + " (" + age + ")";
    }
}

public class ComparableExample {
    public static void main(String[] args) {
        Person[] people = {
            new Person("Alice", 25),
            new Person("Bob", 22),
            new Person("Charlie", 30)
        };

        Arrays.sort(people); // 按 `Comparable` 規(guī)則排序
        System.out.println(Arrays.toString(people));
    }
}

輸出結(jié)果:

[Bob (22), Alice (25), Charlie (30)]

Comparable 的排序方式是 類內(nèi)部固定的,所有調(diào)用 sort() 的地方都使用同樣的規(guī)則。

1.2 Comparator 接口(自定義排序)

  • Comparator 是一個 外部比較器,可以用于自定義排序規(guī)則。

  • 需要實現(xiàn) compare() 方法,可以在不同場景使用不同的比較邏輯。

  • 適用于對象有 多種排序需求,如按年齡、姓名、ID 等。

代碼示例(按 name 進(jìn)行字母升序排序):

class NameComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p1.name.compareTo(p2.name); // 按名稱字母升序
    }
}

public class ComparatorExample {
    public static void main(String[] args) {
        List<Person> people = new ArrayList<>();
        people.add(new Person("Alice", 25));
        people.add(new Person("Bob", 22));
        people.add(new Person("Charlie", 30));

        people.sort(new NameComparator()); // 使用外部比較器進(jìn)行排序
        System.out.println(people);
    }
}

輸出結(jié)果:

[Alice (25), Bob (22), Charlie (30)]

使用 Comparator 可以定義多種排序規(guī)則,不同的需求可以使用不同的比較器,非常靈活。

二、升序和降序排序?qū)崿F(xiàn)

2.1 Comparable 的升序和降序

在 Comparable 中,只能通過修改 compareTo() 方法來改變排序順序:

@Override
public int compareTo(Person other) {
    return Integer.compare(other.age, this.age); // 降序排序
}

2.2 Comparator 的升序和降序

使用 Comparator 可以輕松實現(xiàn) 不同排序方式

Comparator<Person> ageAscending = Comparator.comparingInt(p -> p.age); // 按年齡升序
Comparator<Person> ageDescending = (p1, p2) -> Integer.compare(p2.age, p1.age); // 按年齡降序

代碼示例:

people.sort(ageAscending);  // 升序排序
people.sort(ageDescending); // 降序排序

使用 Java 8 的 Lambda 表達(dá)式: 

people.sort((p1, p2) -> p1.name.compareTo(p2.name)); // 按姓名排序

三. 底層排序?qū)崿F(xiàn)

在 Java 中,Arrays.sort() 和 Collections.sort() 在不同數(shù)據(jù)類型下采用不同的排序算法:

3.1 Arrays.sort()(適用于數(shù)組)

  • Arrays.sort() 主要用于 數(shù)組排序,其底層實現(xiàn)因數(shù)據(jù)類型不同而有所不同:

  • 基本類型(int[]、double[] 等):使用 Dual-Pivot Quicksort(雙軸快速排序),這是 Quicksort 的一種優(yōu)化版本。

  • 對象類型(Integer[]、String[] 等):使用 TimSort(歸并排序 + 插入排序的優(yōu)化組合)

3.1.1 基本類型:雙軸快速排序

對于 int[]、double[] 等基本數(shù)據(jù)類型的數(shù)組排序,Arrays.sort() 使用的是 雙軸快速排序(Dual-Pivot Quicksort),它是由 Vladimir Yaroslavskiy 在 2009 年提出的改進(jìn)版 快速排序,其核心思想是:

  • 選取兩個基準(zhǔn)點(pivot),將數(shù)組劃分為 三個部分

    • 小于第一個 pivot 的部分

    • 介于兩個 pivot 之間的部分

    • 大于第二個 pivot 的部分

  • 遞歸對三個子數(shù)組進(jìn)行排序。

這種優(yōu)化相比于傳統(tǒng)的單軸快速排序,減少了遞歸調(diào)用的次數(shù),提高了排序效率。

源碼分析

在 Arrays.sort(int[] a) 的源碼中:

public static void sort(int[] a) {
    DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}

它會調(diào)用 DualPivotQuicksort.sort(),具體實現(xiàn)如下:

static void sort(int[] a, int left, int right, int[] work, int workBase, int workLen) {
    if (right - left < QUICKSORT_THRESHOLD) {
        insertionSort(a, left, right); // 小數(shù)組使用插入排序
        return;
    }

    int pivot1 = a[left], pivot2 = a[right];
    if (pivot1 > pivot2) {
        swap(a, left, right);
        pivot1 = a[left];
        pivot2 = a[right];
    }

    int less = left + 1;
    int great = right - 1;

    for (int k = less; k <= great; k++) {
        if (a[k] < pivot1) {
            swap(a, k, less++);
        } else if (a[k] > pivot2) {
            swap(a, k, great--);
        }
    }

    sort(a, left, less - 1, work, workBase, workLen);
    sort(a, less, great, work, workBase, workLen);
    sort(a, great + 1, right, work, workBase, workLen);
}

可以看出,Dual-Pivot Quicksort 主要優(yōu)化點

  • 雙軸劃分:比傳統(tǒng)快速排序減少遞歸層數(shù),提高效率。

  • 小數(shù)據(jù)量時使用插入排序,減少不必要的遞歸。

3.1.2對象類型:TimSort(改進(jìn)版歸并排序)

對于對象數(shù)組(如 Integer[]、String[]),Java 采用的是 TimSort,它結(jié)合了 歸并排序(MergeSort)+ 插入排序(InsertionSort),并做了一些優(yōu)化:

  • 數(shù)據(jù)預(yù)處理:TimSort 先尋找 已經(jīng)排序的子序列(run),如果數(shù)據(jù)本身有部分有序,它可以減少比較次數(shù)。

  • 小規(guī)模數(shù)據(jù)使用插入排序:避免小規(guī)模數(shù)據(jù)使用歸并排序?qū)е麻_銷大。

  • 智能歸并:選擇合適的子序列進(jìn)行合并,避免不必要的合并操作,提高效率。

源碼分析:

public static <T> void sort(T[] a, Comparator<? super T> c) {
    if (c == null) {
        Arrays.sort(a); // 調(diào)用默認(rèn)的 Comparable 方式排序
    } else {
        TimSort.sort(a, c); // 使用 Comparator 進(jìn)行排序
    }
}

核心代碼:

static <T> void sort(T[] a, Comparator<? super T> c) {
    int lo = 0, hi = a.length;
    if (hi - lo < INSERTION_SORT_THRESHOLD) {
        insertionSort(a, lo, hi, c); // 小數(shù)據(jù)量使用插入排序
        return;
    }
    int mid = (lo + hi) >>> 1;
    sort(a, lo, mid, c);
    sort(a, mid, hi, c);
    merge(a, lo, mid, hi, c); // 歸并兩個有序數(shù)組
}

TimSort 的優(yōu)點:

  • 適用于部分有序的數(shù)據(jù),比傳統(tǒng)歸并排序更快。

  • 避免不必要的合并,提高效率。

3.2. Collections.sort() 的底層實現(xiàn)

Collections.sort() 主要用于 List 進(jìn)行排序,它本質(zhì)上是 List 的 Arrays.sort(),所以它的底層也是 TimSort。

public static <T extends Comparable<? super T>> void sort(List<T> list) {
    Object[] array = list.toArray();
    Arrays.sort(array);
    for (int i = 0; i < list.size(); i++)
        list.set(i, (T) array[i]);
}

它的執(zhí)行過程

  • 將 List 轉(zhuǎn)換成數(shù)組

  • 調(diào)用 Arrays.sort() 進(jìn)行排序

  • 再把排好序的數(shù)組元素賦值回 List

這意味著 Collections.sort() 的底層仍然是 TimSort

排序方法適用范圍底層實現(xiàn)
Arrays.sort(int[])基本類型數(shù)組Dual-Pivot Quicksort(雙軸快速排序)
Arrays.sort(T[])對象數(shù)組TimSort(歸并排序 + 插入排序優(yōu)化)
Collections.sort(List<T>)List 容器TimSort(底層調(diào)用 Arrays.sort())
Arrays.sort(arr, Comparator)自定義對象排序TimSort(支持 Comparator)

四、結(jié)論與總結(jié)

  • Comparable 適用于對象有固定的排序方式,如 StringInteger,實現(xiàn) compareTo() 進(jìn)行排序。

  • Comparator 適用于需要多個排序規(guī)則的情況,可以使用 compare() 進(jìn)行定制排序。

  • 底層排序算法

    • 基本類型使用 Dual-Pivot QuickSort(雙軸快排)。

    • 對象類型和 List 使用 TimSort(歸并排序 + 插入排序優(yōu)化)。

  • Comparator 更靈活,可以動態(tài)傳遞不同的比較器,適用于多種排序需求。

掌握 Comparable 和 Comparator,可以幫助你在開發(fā)中實現(xiàn)更高效的排序邏輯!

到此這篇關(guān)于Java中比較器Comparable和Comparator的文章就介紹到這了,更多相關(guān)Java比較器Comparable和Comparator內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot項目的漏洞修復(fù)經(jīng)驗分享

    SpringBoot項目的漏洞修復(fù)經(jīng)驗分享

    在局域網(wǎng)環(huán)境下,由于無法連接外網(wǎng)下載Maven包,常見解決方案是在外網(wǎng)環(huán)境搭建相同的開發(fā)環(huán)境以便更新Maven包,本次漏洞掃描包括Tomcat、jackson-databind、fastjson、logback等組件,通常解決方法是升級到更高版本
    2024-10-10
  • ThreadLocal的set方法原理示例解析

    ThreadLocal的set方法原理示例解析

    這篇文章主要為大家介紹了ThreadLocal的set方法原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Linux下用java -jar運行可執(zhí)行jar包的方法教程

    Linux下用java -jar運行可執(zhí)行jar包的方法教程

    這篇文章主要給大家介紹了在Linux下用java -jar運行可執(zhí)行jar包的方法教程,文中介紹的非常詳細(xì),相信對大家的工作或者學(xué)習(xí)具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-05-05
  • Java基于遞歸和循環(huán)兩種方式實現(xiàn)未知維度集合的笛卡爾積算法示例

    Java基于遞歸和循環(huán)兩種方式實現(xiàn)未知維度集合的笛卡爾積算法示例

    這篇文章主要介紹了Java基于遞歸和循環(huán)兩種方式實現(xiàn)未知維度集合的笛卡爾積算法,結(jié)合實例形式分析了Java使用遞歸與循環(huán)兩種方式實現(xiàn)未知維度集合的笛卡爾積相關(guān)概念、原理與操作技巧,需要的朋友可以參考下
    2017-12-12
  • Spring中@ControllerAdvice注解的用法解析

    Spring中@ControllerAdvice注解的用法解析

    這篇文章主要介紹了Spring中@ControllerAdvice注解的用法解析,顧名思義,@ControllerAdvice就是@Controller 的增強版,@ControllerAdvice主要用來處理全局?jǐn)?shù)據(jù),一般搭配@ExceptionHandler、@ModelAttribute以及@InitBinder使用,需要的朋友可以參考下
    2023-10-10
  • 解決java.lang.IllegalArgumentException異常問題

    解決java.lang.IllegalArgumentException異常問題

    這篇文章主要介紹了解決java.lang.IllegalArgumentException異常問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • java實現(xiàn)百度云OCR文字識別 高精度OCR識別身份證信息

    java實現(xiàn)百度云OCR文字識別 高精度OCR識別身份證信息

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)百度云OCR文字識別,高精度OCR識別身份證信息,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Java中的值傳遞以及引用傳遞和數(shù)組傳遞詳解

    Java中的值傳遞以及引用傳遞和數(shù)組傳遞詳解

    這篇文章主要介紹了Java中的值傳遞以及引用傳遞和數(shù)組傳遞詳解,Java不允許程序員選擇按值傳遞還是按引用傳遞各個參數(shù),就對象而言,不是將對象本身傳遞給方法,而是將對象的的引用或者說對象的首地址傳遞給方法,引用本身是按值傳遞的,需要的朋友可以參考下
    2023-07-07
  • SpringBoot2 整合Nacos組件及環(huán)境搭建和入門案例解析

    SpringBoot2 整合Nacos組件及環(huán)境搭建和入門案例解析

    這篇文章主要介紹了SpringBoot2 整合Nacos組件,環(huán)境搭建和入門案例詳解,在整合springboot2時注意版本 0.2.x.RELEASE 對應(yīng)的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 對應(yīng)的是 Spring Boot 1.x 版本,具體內(nèi)容詳情跟隨小編一起看看吧
    2022-03-03
  • java控制臺實現(xiàn)學(xué)生管理系統(tǒng)

    java控制臺實現(xiàn)學(xué)生管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java控制臺實現(xiàn)簡單的學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02

最新評論