最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的Comparable接口和Comparator接口核心機(jī)制詳解

 更新時間:2025年11月14日 09:47:26   作者:ty正在添磚Java  
Java中的Comparable和Comparator接口是實現(xiàn)對象比較和排序的兩種核心機(jī)制,本文給大家介紹Java中的Comparable接口和Comparator接口區(qū)別,感興趣的朋友一起看看吧

 Java 中的ComparableComparator接口是實現(xiàn)對象比較和排序的兩種核心機(jī)制。

一個生動的比喻

想象一下排序一班的學(xué)生:

  • 使用 Comparable(自然排序):
    • 就像是規(guī)定:我們班默認(rèn)的、永久的排隊規(guī)則就是按學(xué)號排。每個學(xué)生(對象)的學(xué)號(自然屬性)是固定的。老師只需要喊一聲“按默認(rèn)規(guī)則排隊!”,學(xué)生A(this)就知道自己應(yīng)該站在學(xué)生B(other)的前面還是后面,因為他們都清楚自己的學(xué)號。
    • 結(jié)論:你只能有一種默認(rèn)規(guī)則。
  • 使用Comparator(定制排序):
    • 就像是老師今天說:“今天我們不按學(xué)號了,我們來按身高排”,于是老師(Comparator)拿著尺子(compare方法)來比較學(xué)生A(o1)和學(xué)生B(o2)的身高,然后決定他們的順序。明天老師可以說:“今天按上次考試成績排”,又拿出一個成績單比較器。
    • 結(jié)論:你可以有無數(shù)種臨時規(guī)則。

一、Comparable接口(內(nèi)部比較器)

當(dāng)一個類實現(xiàn)了 Comparable接口,就表明它的實例具有一種天生的、默認(rèn)的比較順序。例如,String、Integer、Date等類都實現(xiàn)了 Comparable,所以我們可以直接對它們的列表進(jìn)行排序。 

核心:重寫接口中唯一的 compareTo(T o)方法。

規(guī)則:this(當(dāng)前對象)與參數(shù)對象 o比較。

返回一個負(fù)整數(shù)、零或正整數(shù),分別表示 this小于、等于或大于 o。

下面我們舉一個例子分別實現(xiàn)對Student的年齡和姓名進(jìn)行比較:

年齡比較:

import java.util.Arrays;
//類實現(xiàn)接口,使其具備比較的功能
class Student implements Comparable<Student>{
    private String name;
    private int age;
    public Student(String name,int age){
        this.name = name;
        this.age = age;
    }
    public int getAge() {
        return age;
    }
    public String getName(){
        return name;
    }
    //年齡排序
    public int compareTo(Student o){
//        return this.age - o.age;
        return Integer.compare(this.age,o.age);
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Test01 {
    public static void main(String[] args) {
        //按照年齡從小到大排序
        Student[] students = new Student[]{
                new Student("xiaoming", 19),
                new Student("xiaohong",20),
                new Student("xiaohua",15),
                new Student("xiaoshuai",24),
        };
        System.out.println("排序前"+ Arrays.toString(students));
        //Arrays.sort()能夠根據(jù)我們定義的 compareTo方法排序
        Arrays.sort(students);  
        System.out.println("排序后" + Arrays.toString(students));
            //兩個對象進(jìn)行比較
//        Student student1 = new Student("小明",28);
//        Student student2 = new Student("小紅",19);
//        System.out.println(student1.compareTo(student2));    //輸出9
//        <0 則s1<s2 =0則s1=s2 >0則s1>s2
}

修改一下Student類中的compareTo方法可以實現(xiàn)對姓名進(jìn)行排序

//姓名排序
   public int compareTo(Student o){
       return this.name.compareTo(o.name);//在String中已經(jīng)實現(xiàn)了compareTo方法,這里可直接調(diào)用
   }

根據(jù)ASCII值進(jìn)行排序

為什么當(dāng)我們的類實現(xiàn)了comparable接口后,我們能夠直接通過Arrays.sort()方法對students數(shù)組按年齡或者姓名進(jìn)行排序?

這是因為Arrays.sort()依賴于我們通過Comparable接口提供的比較規(guī)則。排序算法本身不知道如何比較兩個Student對象,但是它知道可以調(diào)用我們實現(xiàn)的compareTo方法來獲得比較結(jié)果,從而完成排序。

二、Comparator接口(外部比較器)

Comparator允許在不修改原類的情況下定義多種排序規(guī)則,是一種獨立的比較器,更加靈活(定制排序)。

如何使用?

1.創(chuàng)建一個類實現(xiàn)Comparator<T>接口

2.重寫接口中的 compare(T o1, T o2)方法。

  • 規(guī)則:比較兩個參數(shù)對象 o1和 o2。
  • 返回一個負(fù)整數(shù)、零或正整數(shù),分別表示 o1小于、等于或大于 o2。

下面我們舉一個例子分別實現(xiàn)對Student的年齡和姓名進(jìn)行比較:

按年齡以及姓名長度比較:

import java.util.Arrays;
import java.util.Comparator;
class Teacher{
    private String name;
    private int age;
    public Teacher(String name,int age){
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Test02 {
    public static void main(String[] args) {
        Teacher[] teachers = new Teacher[]{
                new Teacher("Zhang",33),
                new Teacher("Li",40),
                new Teacher("Hen",28),
                new Teacher("Tang",18)
        };
        //按照年齡大小比較
        AgeComparator ageComparator = new AgeComparator();
        System.out.println("排序前" + Arrays.toString(teachers));
        Arrays.sort(teachers,ageComparator);    //將實例化的比較器作為參數(shù)傳入sort
        System.out.println("按年齡排序后" + Arrays.toString(teachers));
        //按照姓名長度比較
        NameLenComparator nameLenComparator = new NameLenComparator();
        Arrays.sort(teachers,nameLenComparator);    //將實例化的比較器作為參數(shù)傳入sort
        System.out.println("按姓名長度排序后" + Arrays.toString(teachers));
    }
    //(靜態(tài)內(nèi)部類)自定義年齡比較器
    static class AgeComparator implements Comparator<Teacher>{
        public int compare(Teacher o1,Teacher o2){
            return o1.getAge()- o2.getAge();
        }
    }
    //(靜態(tài)內(nèi)部類)自定義姓名長度比較器
    static class NameLenComparator implements Comparator<Teacher>{
        public int compare(Teacher o1,Teacher o2){
            return o1.getName().length() - o2.getName().length();
        }
    }
}

我們發(fā)現(xiàn),當(dāng)我們實現(xiàn)了Comparator接口,使用Arrays.sort()時,將我們自定義的比較器實例化的對象作為參數(shù)傳入sort中實現(xiàn)了自定義排序,這使我們能夠自定義多種比較器且不改變原有類進(jìn)行排序,非常靈活。

Java8+引入的Lambda表達(dá)式

Java8+中我們可以通過Lambda表達(dá)式來簡化我們的比較器代碼:

// 使用Lambda表達(dá)式替代完整的比較器類
        // 按年齡排序
        Arrays.sort(teachers, (t1, t2) -> t1.getAge() - t2.getAge());
        System.out.println("按年齡排序后: " + Arrays.toString(teachers));
        // 按姓名長度排序
        Arrays.sort(teachers, (t1, t2) -> t1.getName().length() - t2.getName().length());
        System.out.println("按姓名長度排序后: " + Arrays.toString(teachers));
        // 甚至可以更復(fù)雜:先按年齡,年齡相同按姓名長度
        Arrays.sort(teachers, (t1, t2) -> {
            int ageCompare = t1.getAge() - t2.getAge();
            if (ageCompare != 0) {
                return ageCompare;
            }
            return t1.getName().length() - t2.getName().length();
        });
        System.out.println("按年齡和姓名長度排序后: " + Arrays.toString(teachers));
    }

下面我們來詳解一下這串代碼中Lambda表達(dá)式的用法:

// 按年齡排序
Arrays.sort(teachers, (t1, t2) -> t1.getAge() - t2.getAge());

分解說明:

  • (t1, t2):Lambda的參數(shù)列表,對應(yīng)Comparator接口的compare方法的兩個參數(shù)
  • ->:Lambda操作符,分隔參數(shù)和實現(xiàn)體
  • t1.getAge() - t2.getAge():Lambda的實現(xiàn)體,只有一行表達(dá)式,自動返回結(jié)果

帶代碼塊的Lambda表達(dá)式

// 先按年齡,年齡相同按姓名長度
Arrays.sort(teachers, (t1, t2) -> {
    int ageCompare = t1.getAge() - t2.getAge();
    if (ageCompare != 0) {
        return ageCompare;
    }
    return t1.getName().length() - t2.getName().length();
});

分解說明:

  • 當(dāng)實現(xiàn)邏輯需要多行代碼時,使用{}包裹代碼塊
  • 代碼塊中需要顯式使用return語句返回值
  • 這種多行Lambda適合處理復(fù)雜的比較邏輯

三、如何選擇兩個接口

Comparable接口和Comparator接口關(guān)鍵區(qū)別對比:

使用Comparable的情況

? 對象有明確的、唯一的自然排序規(guī)則

? 排序規(guī)則是對象固有的、不會改變的特性

? 你能夠修改類的源代碼

? 該排序規(guī)則會被頻繁使用

示例:String, Integer, Date, BigDecimal

使用Comparator的情況

? 需要多種不同的排序規(guī)則

? 不能或不想修改原類代碼

? 排序規(guī)則是臨時的或特定于某個業(yè)務(wù)場景

? 需要復(fù)雜的、組合的排序邏輯

示例:報表排序、UI表格列排序、特殊業(yè)務(wù)規(guī)則排序

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

相關(guān)文章

  • Python學(xué)習(xí)之書寫格式及變量命名

    Python學(xué)習(xí)之書寫格式及變量命名

    這篇文章我們給大家總結(jié)了關(guān)于Python書寫格式及變量命名,小編覺得這篇文章寫的還不錯,有興趣的朋友跟著參考學(xué)習(xí)下,希望能夠給你帶來幫助
    2021-10-10
  • Java多線程通信:交替打印ABAB實例

    Java多線程通信:交替打印ABAB實例

    這篇文章主要介紹了Java多線程通信:交替打印ABAB實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • spring的applicationContext.xml文件與NamespaceHandler解析

    spring的applicationContext.xml文件與NamespaceHandler解析

    這篇文章主要介紹了spring的applicationContext.xml文件與NamespaceHandler解析,Spring容器啟動,在創(chuàng)建BeanFactory時,需要加載和解析當(dāng)前ApplicationContext對應(yīng)的配置文件applicationContext.xml,從而獲取bean相關(guān)的配置信息,需要的朋友可以參考下
    2023-12-12
  • Java中使用異或運算符實現(xiàn)加密字符串

    Java中使用異或運算符實現(xiàn)加密字符串

    這篇文章主要介紹了Java中使用異或運算符實現(xiàn)加密字符串,本文直接給出實現(xiàn)代碼,以及運算結(jié)果加密實例,需要的朋友可以參考下
    2015-06-06
  • Gateway+Swagger2配置聚合文檔方式

    Gateway+Swagger2配置聚合文檔方式

    這篇文章主要介紹了Gateway+Swagger2配置聚合文檔方式,具有很好的參考價值,希望對大家有所幫助。
    2023-03-03
  • Spring 緩存抽象示例詳解

    Spring 緩存抽象示例詳解

    Spring框架自身并沒有實現(xiàn)緩存解決方案,但是從3.1開始定義了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口,提供對緩存功能的聲明,能夠與多種流行的緩存實現(xiàn)集成。這篇文章主要介紹了Spring 緩存抽象 ,需要的朋友可以參考下
    2018-09-09
  • Java斷點續(xù)傳(文件分塊)完整實現(xiàn)步驟

    Java斷點續(xù)傳(文件分塊)完整實現(xiàn)步驟

    這篇文章主要介紹了Java斷點續(xù)傳(文件分塊)完整實現(xiàn)步驟,?斷點續(xù)傳通過分塊傳輸大文件,中斷后可續(xù)傳未完成部分,服務(wù)端合并分塊,避免重復(fù)上傳,提升用戶體驗并節(jié)省網(wǎng)絡(luò)資源,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-05-05
  • Java基礎(chǔ)學(xué)習(xí)之實參和形參

    Java基礎(chǔ)學(xué)習(xí)之實參和形參

    這篇文章主要介紹了Java基礎(chǔ)學(xué)習(xí)之實參形參,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有一定的幫助,需要的朋友可以參考下
    2021-05-05
  • Java線程之間通信的幾種方式詳解

    Java線程之間通信的幾種方式詳解

    在 Java 中,線程之間的通信是通過共享內(nèi)存模型來實現(xiàn)的,線程通過共享的對象和變量來交換數(shù)據(jù),為了確保線程間通信的正確性,Java 提供了一系列機(jī)制來實現(xiàn)線程安全、同步和通信,以下是常用的幾種線程間通信的方式,以及它們的使用方法和場景,需要的朋友可以參考下
    2025-03-03
  • java.lang.NullPointerException異常的幾種原因及解決方案

    java.lang.NullPointerException異常的幾種原因及解決方案

    本文主要介紹了java.lang.NullPointerException異常的幾種原因及解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04

最新評論

苍溪县| 通州区| 施甸县| 图木舒克市| 隆化县| 石狮市| 南乐县| 河源市| 合阳县| 宜都市| 樟树市| 乌苏市| 建瓯市| 黄平县| 龙州县| 葫芦岛市| 武鸣县| 永丰县| 宝坻区| 六安市| 双峰县| 仙游县| 正安县| 桃江县| 大关县| 邳州市| 莲花县| 余姚市| 奉节县| 定陶县| 新宁县| 乌审旗| 镇远县| 武义县| 绵竹市| 凌源市| 富民县| 砀山县| 鄂托克旗| 桃江县| 怀远县|