2.1. Comparable vs. Comparator

Comparable 和 Comparator 是Java核心API提供的兩個(gè)接口,通過它們的名字,我們可以說它們也許用來通過某種方式來進(jìn)行比較。但是準(zhǔn)確來說它們是什么,它們之間有什么區(qū)別那。下面的兩個(gè)例子來回答這個(gè)問題。下面的例子比較了HDTV的大小,如何用它們,讀完代碼后會(huì)有明確的認(rèn)識(shí)。

1.Comparable

Comparable 被類實(shí)現(xiàn),用來比較這個(gè)類的兩個(gè)對(duì)象。類必須實(shí)現(xiàn)這個(gè)接口,才能在它的對(duì)象間進(jìn)行比較。需要實(shí)現(xiàn)的方法是compareTo().下面是例子:

class HDTV implements Comparable<HDTV> {
    private int size;
    private String brand;
 
    public HDTV(int size, String brand) {
        this.size = size;
        this.brand = brand;
    }
 
    public int getSize() {
        return size;
    }
 
    public void setSize(int size) {
        this.size = size;
    }
 
    public String getBrand() {
        return brand;
    }
 
    public void setBrand(String brand) {
        this.brand = brand;
    }
 
    @Override
    public int compareTo(HDTV tv) {
 
        if (this.getSize() > tv.getSize())
            return 1;
        else if (this.getSize() < tv.getSize())
            return -1;
        else
            return 0;
    }
}
 
public class Main {
    public static void main(String[] args) {
        HDTV tv1 = new HDTV(55, "Samsung");
        HDTV tv2 = new HDTV(60, "Sony");
 
        if (tv1.compareTo(tv2) > 0) {
            System.out.println(tv1.getBrand() + " is better.");
        } else {
            System.out.println(tv2.getBrand() + " is better.");
        }
    }
}

2. Comparator

在某些條件下,你也許想不改變類的情況下使它具有可比較性。 在這種情況下。Comparator 可以被用做基于對(duì)象的特定屬性和字段進(jìn)行比較。舉個(gè)例子,兩個(gè)人可以通過‘身高’或‘年齡’進(jìn)行比較等。

需要實(shí)現(xiàn)的方法是compare()。現(xiàn)在我們用另外一種方式通過Size來比較HDTV。一個(gè)Comparator最通常的做法是排序。無(wú)論是Collection還是Arrays類都用Comparator來提供一個(gè)排序的方法。

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
 
class HDTV {
    private int size;
    private String brand;
 
    public HDTV(int size, String brand) {
        this.size = size;
        this.brand = brand;
    }
 
    public int getSize() {
        return size;
    }
 
    public void setSize(int size) {
        this.size = size;
    }
 
    public String getBrand() {
        return brand;
    }
 
    public void setBrand(String brand) {
        this.brand = brand;
    }
}
 
class SizeComparator implements Comparator<HDTV> {
    @Override
    public int compare(HDTV tv1, HDTV tv2) {
        int tv1Size = tv1.getSize();
        int tv2Size = tv2.getSize();
 
        if (tv1Size > tv2Size) {
            return 1;
        } else if (tv1Size < tv2Size) {
            return -1;
        } else {
            return 0;
        }
    }
}
 
public class Main {
    public static void main(String[] args) {
        HDTV tv1 = new HDTV(55, "Samsung");
        HDTV tv2 = new HDTV(60, "Sony");
        HDTV tv3 = new HDTV(42, "Panasonic");
 
        ArrayList<HDTV> al = new ArrayList<HDTV>();
        al.add(tv1);
        al.add(tv2);
        al.add(tv3);
 
        Collections.sort(al, new SizeComparator());
        for (HDTV a : al) {
            System.out.println(a.getBrand());
        }
    }
}

輸出:
···
Panasonic
Samsung
Sony
···
另外我們常用Collections.reverseOrder()方法來獲得一個(gè)倒序的比較器,如下:

ArrayList<Integer> al = new ArrayList<Integer>();
al.add(3);
al.add(1);
al.add(2);
System.out.println(al);
Collections.sort(al);
System.out.println(al);
 
Comparator<Integer> comparator = Collections.reverseOrder();
Collections.sort(al,comparator);
System.out.println(al);

輸出:

[3,1,2]
[1,2,3]
[3,2,1]

3. 如何使用

簡(jiǎn)單來說,一個(gè)實(shí)現(xiàn)Comparable的類將是可比較的,這意味著它的對(duì)象可以相互比較。

一個(gè)實(shí)現(xiàn)Comparator經(jīng)常用在兩個(gè)情景:
1)它常被傳遞給一個(gè)排序方法,比如Collections.sort()或者Arrays.sort(),以在排序中進(jìn)行精確控制。
2)它也常用來控制特定數(shù)據(jù)結(jié)構(gòu)的順序,比如一個(gè)排序的sets(例如TreeSet)或者排序的map(例如TreeMap)

舉個(gè)例子,在創(chuàng)建TreeSet ,我們可以創(chuàng)建一個(gè)可比較對(duì)象或者傳遞一個(gè)comparator的構(gòu)造。

方法一1 -TreeSet(Comparator comparator)

class Dog {
    int size;
 
    Dog(int s) {
        size = s;
    }
}
 
class SizeComparator implements Comparator<Dog> {
    @Override
    public int compare(Dog d1, Dog d2) {
        return d1.size - d2.size;
    }
}
 
public class ImpComparable {
    public static void main(String[] args) {
        TreeSet<Dog> d = new TreeSet<Dog>(new SizeComparator()); // pass comparator
        d.add(new Dog(1));
        d.add(new Dog(2));
        d.add(new Dog(1));
    }
}

方法二,實(shí)現(xiàn)Comparable

class Dog implements Comparable<Dog>{
    int size;
 
    Dog(int s) {
        size = s;
    }
 
    @Override
    public int compareTo(Dog o) {
        return o.size - this.size;
    }
}
 
public class ImpComparable {
    public static void main(String[] args) {
        TreeSet<Dog> d = new TreeSet<Dog>();
        d.add(new Dog(1));
        d.add(new Dog(2));
        d.add(new Dog(1));
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,787評(píng)論 11 349
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,638評(píng)論 18 399
  • 1.import static是Java 5增加的功能,就是將Import類中的靜態(tài)方法,可以作為本類的靜態(tài)方法來...
    XLsn0w閱讀 1,424評(píng)論 0 2
  • 面向?qū)ο笾饕槍?duì)面向過程。 面向過程的基本單元是函數(shù)。 什么是對(duì)象:EVERYTHING IS OBJECT(萬(wàn)物...
    sinpi閱讀 1,220評(píng)論 0 4
  • —我沒心 我:那你的心在哪? —一出生就沒了 我:我有,我分你一半 —你那么花心??? 我:我只有一顆心 —… 我:...
    流水依舊只東去閱讀 381評(píng)論 0 0

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