【Java SE】Java比較器:Comparable、Comparator

目錄

1.前言

2.Comaprable接口

2.1 使用細節

2.2 案例演示

3.Comparator接口

3.1 為什么需要Comparator接口

3.2 使用細節

3.3 案例演示

4.Comparable、Comparator對比


1.前言

Java 中的對象,正常情況下,只能進行比較:== ?或 ?!= 。不能使用 >< 。但是在實際開發場景中,有時候需要對多個對象進行排序,言外之意,就是需要比較對象的大小。這便引出了?Comparable、Comparator 兩個接口

2.Comaprable接口

Comparable 位于 java.lang.Comaprable,其源碼如下:

package java.lang;
import java.util.*;
public interface Comparable<T> {public int compareTo(T o);
}

2.1 使用細節

實現 Comparable?接口的類必須實現 int compareTo(T o)?方法,兩個對象可以通過 int compareTo(T o) 方法的返回值來比較大小:

? ? ? ? (1)當前對象 this 大于形參對象 o,則返回正整數

????????(2)當前對象 this 小于形參對象 o,則返回負整數

????????(3)當前對象 this 等于形參對象 o,則返回 0

?實現 Comparable 接口的對象列表或數組可以通過 Collections.sort Arrays.sort 進行自動排序,無需指定 Collection.sort(...)、Arrays.sort(...) 方法的第二個比較器參數,底層會根據類中實現的?int compareTo(T o)? 作為排序邏輯

String、八大包裝類implements 了該接口,并實現了 int compareTo(T o) 方法,都是從小到大排列的

String:按照字符串中字符的 ASCII?值進行比較
Character:按照字符的 ASCII?值來進行比較
數值類型對應的包裝類以及 BigInteger、BigDecimal :按照它們對應的數值大小進行比較
Boolean:true 對應的包裝類實例大于 false 對應的包裝類實例
Date、Time等:后面的日期時間比前面的日期時間大

2.2 案例演示

案例1 :根據學生的年齡對學生類型數組進行升序排序?

import java.util.Arrays;
import java.util.Comparator;
public class demo {public static void main(String[] args) {Student s1 = new Student("小馬", 100);Student s2 = new Student("蔡徐坤", 5);Student s3 = new Student("ftt", 90);Student[] arr1  = {s1,s2,s3};Student[] arr2  = {s1,s2,s3};System.out.println("排序前,所有學生:");Arrays.stream(arr1).forEach(student -> System.out.println(student));System.out.println("----------------------");//方式1:使用冒泡排序System.out.println("按照年齡排序:");for (int i = 1; i < arr1.length; i++) {for (int j = 0; j < arr1.length-i; j++) {if(arr1[j].compareTo(arr1[j+1])>0){Student temp = arr1[j];arr1[j] = arr1[j+1];arr1[j+1] = temp;}}}Arrays.stream(arr1).forEach(student -> System.out.println(student));System.out.println("----------------------");//方式2:使用Arrays.sort排序,因為在Student類已實現Comparable接口,所以無需指定比較器Arrays.sort(arr2);Arrays.stream(arr2).forEach(student -> System.out.println(student));}
}class Student implements Comparable<Student> {public String name;public int age;public Student(){}public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}//按學生年齡升序排序@Overridepublic int compareTo(Student anotherStudent) {if(this.age > anotherStudent.age){return 1;}else if(this.age < anotherStudent.age){return -1;}else{return 0;}}
}

?案例1運行結果:

案例2?:對字符數組進行排序

import java.util.Arrays;
public class demo {public static void main(String[] args) {Character[] arr = {'b','a','c','d'};System.out.println("排序前的字符數組:"+Arrays.toString(arr));Arrays.sort(arr);//Arrays底層會將Character類中實現的 int compareTo(T o) 方法作為排序邏輯System.out.println("排序后的字符數組:"+Arrays.toString(arr));}
}

?案例2運行結果:?

3.Comparator接口

Comparator 接口位于 java.until.Comparator 下,其中關于 int compareTo(...) 接口的源碼如下:

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

3.1 為什么需要Comparator接口

場景 ① :當只有第三方的類時(即只有 .class 字節碼文件,沒有 .java 源文件,無法修改代碼),且這些類沒有實現 java.lang.Comparable 接口

場景 ② :類中提前實現了 Comparable 接口,指定了兩個對象比較大小的規則,但此時如果不想按照它預定義的方法比較大小,但是又不能隨意修改源碼,因為會影響其他地方的使用,怎么辦呢?

因此,基于?①、②Java?增加了一個 java.util.Comparator 接口來解決問題

3.2 使用細節

通常是用一個單獨的其他的類來實現 Comparator 接口

②?實現 Comparator 的類必須實現 int compareTo (T o1,T o2) 方法,兩個對象可以通過 int compareTo (T o1,T o2) 方法的返回值來比較大小:

? ? ? ? (1)?o1?大于?o2,則返回正整數

????????(2)?o1?小于?o2,則返回負整數

????????(3)?o1?等于?o2,則返回 0

?在使用 Collection.sortArrays.sort 實現排序功能時,可以將實現了 Comparator 接口的類的實例傳遞給 Collection.sortArrays.sort,作為排序邏輯的比較器

3.3 案例演示

案例

import java.util.Arrays;
import java.util.Comparator;
public class demo {public static void main(String[] args) {//定義比較器實例StudentScoreComparator sc = new StudentScoreComparator();Student s1 = new Student("小馬", 22,98);Student s2 = new Student("jack", 55,90);Student s3 = new Student("mary", 30,67);Student[] arr1  = {s1,s2,s3};Student[] arr2  = {s1,s2,s3};System.out.println("按分數排序前,所有學生:");Arrays.stream(arr1).forEach(student -> System.out.println(student));System.out.println("----------------------");//方式1:使用冒泡排序System.out.println("按照分數排序:");for (int i = 1; i < arr1.length; i++) {for (int j = 0; j < arr1.length-i; j++) {if(sc.compare(arr1[j],arr1[j+1]) > 0) {Student temp = arr1[j];arr1[j] = arr1[j+1];arr1[j+1] = temp;}}}Arrays.stream(arr1).forEach(student -> System.out.println(student));System.out.println("----------------------");//方式2:使用Arrays.sort排序,指定StudentScoreComparator為比較器,按學生的分數排序Arrays.sort(arr2,sc);Arrays.stream(arr2).forEach(student -> System.out.println(student));}
}//定制比較器類,按學生的分數升序排序
class StudentScoreComparator implements Comparator<Student>{@Overridepublic int compare(Student s1, Student s2) {if(s1.score > s2.score){return 1;}else if(s1.score < s2.score){return -1;}else{return 0;}}
}class Student implements Comparable<Student> {public String name;public int age;public int score;public Student(){}public Student(String name, int age, int score) {this.name = name;this.age = age;this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';}//按學生年齡升序排序@Overridepublic int compareTo(Student anotherStudent) {if(this.age > anotherStudent.age){return 1;}else if(this.age < anotherStudent.age){return -1;}else{return 0;}}
}

案例1運行結果:?

4.Comparable、Comparator對比

ComparableComparator
實現位置類內部實現外部獨立實現
排序規則數量只能定義一種排序規則可根據業務求定義多種排序規則
侵入性需要修改原類代碼不需要修改原類代碼
方法int compareTo (T o)int compare (T o1, T o2)
使用場景默認排序,如 Arrays.sort(arr)靈活排序,如 Arrays.sort(arr,comparator)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/76046.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76046.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/76046.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

(二)創建實例

在這節中&#xff0c; 創建一個實例初始化Vulkan庫,指定驅動程序需要使用的應用程序信息 1&#xff0c;要有個實例句柄 VkInstance instance; 2&#xff0c;設置創建Vulkan驅動程序需要的信息&#xff0c; VkInstanceCreateInfo createInfo {}; createInfo.sType VK_STRUCTUR…

HCIP之VRRP

1. VRRP是什么 VRRP&#xff08;Virtual Router Redundancy Protocol&#xff0c;虛擬路由冗余協議&#xff09;是一種用于提高網絡可靠性的容錯協議。它通過將多臺路由器虛擬成一臺虛擬路由器&#xff0c;實現網關的冗余備份。當主路由器&#xff08;Master&#xff09;出現故…

高效內存管理:x86-64架構中的分頁機制

在 x86-64 架構的世界里&#xff0c;內存分頁機制扮演著舉足輕重的角色&#xff0c;它就像是一座橋梁&#xff0c;連接著虛擬地址與物理地址。簡單來說&#xff0c;內存分頁機制就是將線性地址&#xff08;也就是虛擬地址&#xff09;切分成一個個固定大小的頁&#xff0c;并把…

【軟件工程】填空題

真題 2024-10 16.數據字典是用來定義_____中各個成分的具體含義的。 17.模塊設計的基本原則是_____。 18.接口是操作的一個集合,其中每個操作描述了類、構件或子系統的一個_____。 19.耦合是指不同模塊之間_____的度量。 20.RUP的突出特點是,它是一種以用況為驅動的、…

第二卷:海鹽城血戰(37-72回)正反人物群像

第二卷&#xff1a;海鹽城血戰&#xff08;37-72回&#xff09;正反人物群像 核心矛盾&#xff1a;寒門軍事崛起 → 內部傾軋 → 制度性腐敗 主題&#xff1a;通過人物群像展現寒門勝利的虛幻性與權力異化的必然性 一、正派陣營&#xff08;寒門抗爭勢力&#xff09; 1. 劉裕…

23_js面向對象

上次我們講運動函數&#xff0c;實際開發不會寫運動函數。只是講一下思想。 現在講一下用原生js去實現輪播圖&#xff0c;引入到對象 首先&#xff0c;要明確 面向對象不是語法&#xff0c;是一個思想&#xff0c;是一種編程模式 面向&#xff1a;朝向 面向對象&#xff1a…

torch不能使用cuda的解決方案

遇到了這樣的報錯&#xff0c;說明 torch不能使用cuda 反思 我頻繁地嘗試安裝不同的 nvdia 驅動&#xff0c;浪費了很多時間。因為我的錯誤地認為nvidia會自帶cuda&#xff0c;其實cuda需要單獨安裝。 還有我的torch是cpu版本的&#xff0c;即使nvidia cuda安裝了&#xff0…

kettle從入門到精通 第九十三課 ETL之kettle kettle 調用web service接口5種方法,一文徹底搞懂

場景&#xff1a;群里有小伙伴向我求助如何調用web service接口&#xff0c;趁著周末時間&#xff0c;給兄弟們搞demo。 1、本次使用的web service服務接口地址是http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?opgetSupportCityDataset&#xff0c; 此接口根據用戶輸入…

藍橋杯 14 天 十五屆藍橋杯 數字詩意

static boolean kkk(long x) {if(x1)return true;else {// 初始化xx為1&#xff0c;用于計算2的冪long xx 1;// 循環60次&#xff0c;檢查2的冪是否等于xfor (int i 1; i < 60; i) {xx * 2; // 每次將xx乘以2if (xx x) { // 如果xx等于x&#xff0c;說明x是2的冪&#xf…

異常與捕獲

1.C 異常概念 異常是一種處理錯誤的方式&#xff0c;當一個函數發現自己無法處理的錯誤時就可以拋出異常&#xff0c;讓函數的直接或間接的調用者處理這個錯誤。 throw&#xff1a;當問題出現時&#xff0c;程序會拋出一個異常。這是通過使用 throw 關鍵字來完成的。catch&am…

2025年最新自動化/控制保研夏令營預推免面試真題分享(東南大學蘇州校區/華東理工/南航/天大)

筆者來2021級本科自動化專業&#xff0c;以下部分將介紹我在夏令營以及預推免期間發生經歷和問題 東南大學蘇州校區蒙納士大學聯培 東南大學蘇州校區的項目算是一個比較小眾的項目&#xff0c;是第一年在蘇州校區&#xff0c;二三年到南京校區找導師&#xff08;不提供住宿自…

【SQL】MySQL基礎2——視圖,存儲過程,游標,約束,觸發器

文章目錄 1. 視圖2. 存儲過程2.1 創建存儲過程2.2 執行存儲過程 3. 游標4. 約束4.1 主鍵約束4.2 外鍵約束4.3 唯一約束4.4 檢查約束 5. 觸發器 1. 視圖 視圖是虛擬的表&#xff0c;它是動態檢索的部分。使用視圖的原因&#xff1a;避免重復的SQL語句&#xff1b;使用表的部分而…

OGG故障指南:OGG-01163 Bad column length (xxx) specified for column

報錯 OGG-01163 Bad column length (xxx) specified for column AAA in table OWNER.TABLE, maximum allowable length is yyy原因 源端修改了字段長度。 雖然源端和目標端的長度已經通過DDL語句修改到一致&#xff0c;在extract進程未重啟的情況下&#xff0c;生成的trail文…

Linux進程狀態補充(10)

文章目錄 前言一、阻塞二、掛起三、運行R四、休眠D五、四個重要概念總結 前言 上篇內容大家看的云里霧里&#xff0c;這實在是正常不過&#xff0c;因為例如 寫實拷貝 等一些概念的深層原理我還沒有講解&#xff0c;大家不用緊張&#xff0c;我們繼續往下學習就行&#xff01;&…

信息學奧賽一本通 1609:【例 4】Cats Transport | 洛谷 CF311B Cats Transport

【題目鏈接】 ybt 1609&#xff1a;【例 4】Cats Transport 洛谷 CF311B Cats Transport 【題目考點】 1. 動態規劃&#xff1a;斜率優化動規 【解題思路】 解法1&#xff1a;設a點的前綴和 輸入的 d d d序列是從 d 2 d_2 d2?到 d n d_n dn?&#xff0c;共n-1個數字。人…

bluecode-20240913_1_數據解碼

時間限制&#xff1a;C/C 1000MS&#xff0c;其他語言 2000MS 內存限制&#xff1a;C/C 256MB&#xff0c;其他語言 512MB 難度&#xff1a;困難 數據解碼 指定有一段經過編碼的二進制數據&#xff0c;數據由0個或多個"編碼單元"組成。"編碼單元"的編碼方式…

接口自動化進階 —— Pytest全局配置pytest.ini文件詳解!

pytest.ini 是 Pytest 的全局配置文件&#xff0c;用于自定義測試運行的行為和規則。通過配置 pytest.ini&#xff0c;可以避免在命令行中重復輸入參數&#xff0c;提升測試的效率和一致性。 1. 配置文件的位置和格式 位置&#xff1a;pytest.ini 文件通常放在項目的根目錄下。…

ModuleNotFoundError: No module named ‘demjson‘

錯誤 ModuleNotFoundError: No module named demjson 表明 Python 無法在其環境中找到名為 demjson 的模塊。demjson 是一個第三方庫&#xff0c;用于在 Python 中編碼和解碼 JSON 數據。如果你嘗試導入它但遇到了這個錯誤&#xff0c;那很可能是因為你的 Python 環境中沒有安裝…

1、C51單片機(STC8G2K64S4)串口實驗

一、串口1接線圖 1、下面是單片機外接電路圖&#xff0c;P30,P31分別用于RXD和TXD功能引腳 2、我們來查看單片機手冊 串口1需要設置的寄存器 串口1的功能腳配置選擇位&#xff0c;看電路圖選擇的是P3.0,P3.1。 3、串口1&#xff1a;SCON控制寄存器 設置為0x50:0101 0000。&a…

3PL EDI:SA Piper Logistics EDI需求分析

SA Piper Logistics成立于2005年&#xff0c;是一家專注于全球供應鏈管理的第三方物流服務商&#xff08;3PL&#xff09;&#xff0c;總部位于美國芝加哥。公司以“優化物流效率&#xff0c;重塑供應鏈價值”為使命&#xff0c;提供倉儲管理、運輸規劃、訂單履行及跨境清關等一…