java自定義對象排序

項目中經(jīng)常會遇到列表搜索查詢,大部分的查詢是可以通過sql語句來實現(xiàn)的,有些特殊的搜索排序sql則實現(xiàn)不了,例如中文排序。。

本文,先介紹Comparable 和Comparator兩個接口,以及它們的差異;接著,通過示例,對它們的使用方法進(jìn)行說明。

Comparable 簡介

Comparable 是排序接口。

若一個類實現(xiàn)了Comparable接口,就意味著“該類支持排序”。

即然實現(xiàn)Comparable接口的類支持排序,假設(shè)現(xiàn)在存在“實現(xiàn)Comparable接口的類的對象的List列表(或數(shù)組)”,則該List列表(或數(shù)組)可以通過

Collections.sort(或 Arrays.sort)進(jìn)行排序。

Comparable 定義

Comparable 接口僅僅只包括一個函數(shù),它的定義如下:

?? ? package java.lang;import java.util.*;

? ?? public interface Comparable {

? ? ? ? ? public int compareTo(T o);

????? }

說明:

假設(shè)我們通過 x.compareTo(y) 來“比較x和y的大小”。若返回“負(fù)數(shù)”,意味著“x比y小”;返回“零”,意味著“x等于y”;返回“正數(shù)”,意味著“x大于y”。

Comparator 簡介

Comparator 是比較器接口。

我們?nèi)粜枰刂颇硞€類的次序,而該類本身不支持排序(即沒有實現(xiàn)Comparable接口);那么,我們可以建立一個“該類的比較器”來進(jìn)行排序。這個“比較器”只需要實現(xiàn)Comparator接口即可。

也就是說,我們可以通過“實現(xiàn)Comparator類來新建一個比較器”,然后通過該比較器對類進(jìn)行排序。

Comparator 定義

Comparator 接口僅僅只包括兩個個函數(shù),它的定義如下:

??? package java.util;

??? public interface Comparator {

??? ? ? ? int? compare(T o1, T o2);? ?

??? ? ? ? boolean equals(Object obj);

??? }

說明:

(01) 若一個類要實現(xiàn)Comparator接口:它一定要實現(xiàn)compare(T o1, T o2) 函數(shù),但可以不實現(xiàn) equals(Object obj) 函數(shù)。

為什么可以不實現(xiàn)

equals(Object obj) 函數(shù)呢? 因為任何類,默認(rèn)都是已經(jīng)實現(xiàn)了equals(Object obj)的。

Java中的一切類都是繼承于java.lang.Object,在Object.java中實現(xiàn)了equals(Object

obj)函數(shù);所以,其它所有的類也相當(dāng)于都實現(xiàn)了該函數(shù)。

(02) int compare(T o1, T o2) 是“比較o1和o2的大小”。返回“負(fù)數(shù)”,意味著“o1比o2小”;返回“零”,意味著“o1等于o2”;返回“正數(shù)”,意味著“o1大于o2”。

Comparator 和 Comparable 比較

Comparable是排序接口;若一個類實現(xiàn)了Comparable接口,就意味著“該類支持排序”。

而Comparator是比較器;我們?nèi)粜枰刂颇硞€類的次序,可以建立一個“該類的比較器”來進(jìn)行排序。

我們不難發(fā)現(xiàn):Comparable相當(dāng)于“內(nèi)部比較器”,而Comparator相當(dāng)于“外部比較器”。

我們通過一個測試程序來對這兩個接口進(jìn)行說明。源碼如下:


import java.util.*;

import java.lang.Comparable;

/**

* @desc "Comparator"和“Comparable”的比較程序。

*? (01) "Comparable"

*? 它是一個排序接口,只包含一個函數(shù)compareTo()。

*? 一個類實現(xiàn)了Comparable接口,就意味著“該類本身支持排序”,它可以直接通過Arrays.sort() 或

Collections.sort()進(jìn)行排序。

*? (02) "Comparator"

*? 它是一個比較器接口,包括兩個函數(shù):compare() 和 equals()。

*? 一個類實現(xiàn)了Comparator接口,那么它就是一個“比較器”。其它的類,可以根據(jù)該比較器去排序。

*? 綜上所述:Comparable是內(nèi)部比較器,而Comparator是外部比較器。

*? 一個類本身實現(xiàn)了Comparable比較器,就意味著它本身支持排序;若它本身沒實現(xiàn)Comparable,也可以通過外部比較

器Comparator進(jìn)行排序。

*/

public class CompareComparatorAndComparableTest{??

?????????????????? public static void main(String[] args) {? ? ??

?????????????????????????? // 新建ArrayList(動態(tài)數(shù)組)? ? ??

????????????????????????? ArrayListlist = new ArrayList();? ? ??

???????????????????????? // 添加對象到ArrayList中? ? ??

????????????????????? ? list.add(new Person("ccc", 20));? ? ??

???????????????????????? list.add(new Person("AAA", 30));? ? ? ?

???????????????????????? list.add(new Person("bbb", 10));? ? ?

? ? ? ? ? ? ? ? ? ? ? ? ?? list.add(new Person("ddd", 40));? ? ??

??????????????????????? // 打印list的原始序列? ? ? ?

????????????????????????? System.out.printf("Original? sort, list:%s\n", list);? ? ??

?????????????????????? // 對list進(jìn)行排序 ,這里會根據(jù)“Person實現(xiàn)的Comparable接口”進(jìn)行排序,即會根據(jù)“name”進(jìn)行排序

?????????????????????????? Collections.sort(list);

????????????????????????? System.out.printf("Name? ? ? sort, list:%s\n", list);

?????????????????????? // 通過“比較器(AscAgeComparator)”,對list進(jìn)行排序

?????????????????????? // AscAgeComparator的排序方式是:根據(jù)“age”的升序排序

????????????????????? Collections.sort(list, new AscAgeComparator());

????????????????????? System.out.printf("Asc(age)? sort, list:%s\n", list);

???????????????????? // 通過“比較器(DescAgeComparator)”,對list進(jìn)行排序

??????????????????? // DescAgeComparator的排序方式是:根據(jù)“age”的降序排序

???????????????????? Collections.sort(list, new DescAgeComparator());

????????????????????? System.out.printf("Desc(age) sort, list:%s\n", list);

???????????????????? // 判斷兩個person是否相等

?????????????????????? testEquals();

}

/**

* @desc 測試兩個Person比較是否相等。

*? 由于Person實現(xiàn)了equals()函數(shù):若兩person的age、name都相等,則認(rèn)為這兩個person相等。

*? 所以,這里的p1和p2相等。

*

*? TODO:若去掉Person中的equals()函數(shù),則p1不等于p2

*/

private static void testEquals() {

????????? Person p1 = new Person("eee", 100);

????????? Person p2 = new Person("eee", 100);

????????? if (p1.equals(p2)) {

???????????????? System.out.printf("%s EQUAL %s\n", p1, p2);

?????????? } else {

???????????????? System.out.printf("%s NOT EQUAL %s\n", p1, p2);

????????? }

}

/**? ? * @desc Person類。? ? *? ? ? Person實現(xiàn)了Comparable接口,這意味著Person本身支持排序? ? */??

private static class Person implements Comparable{? ? ?

? ? ? ? ? int age;? ? ? ?

???????? String name;? ? ??

???????? public Person(String name, int age) {? ? ? ? ? ?

?????????????????????????? this.name = name;? ? ? ?

? ? ? ? ? ? ? ? ? ? ? ??? ? this.age = age;? ? ??

???????? }? ? ?

? ? ? ? public String getName() {? ? ? ? ??

????????????????? return name;? ? ??

????????? }? ? ? ?

?? ? ? public int getAge() {? ? ? ? ?

? ? ? ? ? ?? return age;? ? ??

? ? ?? }? ? ?

? ?? public String toString() {? ? ? ? ?

? ? ? ? ? ? ? return name + " - " +age;? ? ?

? ?? }? ? ??

?/**? ? ? ? * 比較兩個Person是否相等:若它們的name和age都相等,則認(rèn)為它們相等? ? ? ? */? ?

? ? ? ? boolean equals(Person person) {? ? ? ? ??

????????????? if (this.age == person.age && this.name == person.name)? ? ? ? ? ? ?

? ? ? ? ? ? ? ? ? ?? return true;? ? ? ? ??

?????????????? return false;? ? ?

? }? ? ??

/**? ? ? ? * @desc 實現(xiàn) “Comparable” 的接口,即重寫compareTo函數(shù)。

*? 這里是通過“person的名字”進(jìn)行比較的

*/

@Override

public int compareTo(Person person) {

???????? return name.compareTo(person.name);

????????? //return this.name - person.name;

}

}

/**? ? * @desc AscAgeComparator比較器? ? *? ??

???????? 它是“Person的age的升序比較器”? ? */??

????? private static class AscAgeComparator implements Comparator{? ? ? ?

??????? @Override? ? ?

? ? ?? public int compare(Person p1, Person p2) {? ? ? ? ??

??????????? return p1.getAge() - p2.getAge();? ? ?

? ? ? ? ? }??

??? }??

??? /**? ? * @desc DescAgeComparator比較器? ? *? ?

? ? ? ? ? 它是“Person的age的升序比較器”? ? */?

?? private static class DescAgeComparator implements Comparator{

? ? ? ? ?? @Override

? ? ? ? ?? public int compare(Person p1, Person p2) {

? ? ? ? ? ? ? ? ? ? ? return p2.getAge() - p1.getAge();

???????????? }

??? }

}

下面對這個程序進(jìn)行說明。

???? a) Person類定義。如下:

?????? private static class Person implements Comparable{??

???????????????????????????? int age;? ? String name;? ? ? ? ...? ?

?????????? /**? ? ? * @desc 實現(xiàn) “Comparable” 的接口,即重寫compareTo函數(shù)。??

??????????????? *? 這里是通過“person的名字”進(jìn)行比較的? ? */?

? ? ? ? ? ? ? ? ?? @Override??

????????????????????? public int compareTo(Person person) {? ? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? return name.compareTo(person.name);? ? ??

?????????????????????????? //return this.name - person.name;?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }?

?????????????????????? }說明:(01) Person類代表一個人,Persong類中有兩個屬性:age(年紀(jì)) 和 name“人名”。

???????????????????????????? (02) Person類實現(xiàn)了Comparable接口,因此它能被排序。

???????????????????????????? b) 在main()中,我們創(chuàng)建了Person的List數(shù)組(list)。

?????????????????????????????? 如下:// 新建ArrayList(動態(tài)數(shù)組)ArrayListlist = new ArrayList();

??????????????????????????????????? // 添加對象到ArrayList中l(wèi)ist.add(new Person("ccc", 20));

??????????????????????????????????? list.add(new Person("AAA", 30));list.add(new Person("bbb", 10));

????????????????????????????????? list.add(new Person("ddd", 40));c)

?????????????????????????????? 接著,我們打印出list的全部元素。如下:

????????????????????????? // 打印list的原始序列System.out.printf("Original sort, list:%s\n", list);d) 然后,我們通過Collections的sort()函數(shù),對list進(jìn)行排序。由于Person實現(xiàn)了Comparable接口,因此通過sort()排序時,會根據(jù)Person支持的排序方式,即 compareTo(Person person) 所定義的規(guī)則進(jìn)行排序。如下:// 對list進(jìn)行排序// 這里會根據(jù)“Person實現(xiàn)的Comparable接口”進(jìn)行排序,即會根據(jù)“name”進(jìn)行排序??????????????????

??????????????????????????? Collections.sort(list);

????????????????????????????? System.out.printf("Name sort, list:%s\n", list);e)

????????????????????????????? 對比Comparable和Comparator我們定義了兩個比較器 AscAgeComparator 和 DescAgeComparator,來分別對Person進(jìn)行 升序 和 降低 排序。

???????????????????????????????? e.1) AscAgeComparator比較器它是將Person按照age進(jìn)行升序排序。代碼如下:

????????????????????????????????? /** * @desc AscAgeComparator比較器 * 它是“Person的age的升序比較器”?? */

???????????????????? private static class AscAgeComparator implements Comparator{??

??????????????????????????? @Override? ?

???????????????????????????? public int compare(Person p1, Person p2) {? ? ??

?????????????????????????????????? return p1.getAge() - p2.getAge();??

??????????????????????????????? }}

????????????????????????? e.2) DescAgeComparator比較器它是將Person按照age進(jìn)行降序排序。代碼如下:/** *

?????????????????????????????? @desc DescAgeComparator比較器 *? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 它是“Person的age的升序比較器” */

??? private static class DescAgeComparator implements Comparator{

???????????????? @Override

?????????????????? public int compare(Person p1, Person p2) {

????????????? ? ? ? ? ? ? return p2.getAge() - p1.getAge();

????????????? }

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,623評論 18 399
  • 從三月份找實習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,755評論 11 349
  • 關(guān)鍵詞: 團(tuán)隊目標(biāo) 團(tuán)隊文化 關(guān)愛 信任 導(dǎo)讀: 新年過后,人心思動,這兩天有朋友在問我如何團(tuán)隊打造中該注意哪些事...
    老鐘說說閱讀 2,154評論 1 32
  • 沒有什么決定是完全正確的,沒有嘗試過的路你無法判斷它是否曲折是否坎坷,更沒有人能憑一己之力改變整個社會的現(xiàn)狀。 大...
    如師說閱讀 310評論 0 2
  • The Java? Tutorials : Bitwise and Bit Shift Operators Jav...
    zheng7閱讀 276評論 0 0

友情鏈接更多精彩內(nèi)容