Java中Comparable和Comparator區別

Comparable

只有一個方法
public int compareTo(T o);

compareTo方法的返回值是int,有三種情況:

1、比較者(調用compareTo方法者)大於被比較者(也就是compareTo方法接受對象),那麼返回 1

2、比較者等於被比較者,那麼返回0

3、比較者小於被比較者,那麼返回 -1

Comparable可以認爲是一個內比較器,很多類都會實現這個接口以提供對該類對象之間比較的默認實現;比如String,Integer,Float,Double類都實現了Comparable接口。實現Comparable接口的類有一個特點,就是這些類提供了自己對象之間比較大小的默認實現,如果開發者add進入一個Collection的對象想要通過Collections的sort方法幫你自動進行排序的話,那麼這個add進入的對象類必須實現Comparable接口。

package org.vincent.strategy.test;

/**
 * 實現一個類如果需要實現比較大小,那麼繼承Comparable接口,泛型參數T 是比較誰就寫誰
 * 
 * @ClassName: Domain
 * @Description: TODO(這裏用一句話描述這個類的作用)
 * @author PengRong
 * @date 2017年3月10日 下午6:41:54
 */
public class Domain implements Comparable<Domain> {

    private String string;

    public String getString() {
        return this.string;
    }

    public void setString(String string) {
        this.string = string;
    }

    public Domain(String name) {
        this.string = name;
    }

    public int compareTo(Domain o) {
        // TODO Auto-generated method stub
        if (this.string.compareTo(o.getString()) > 0)
            return 1;
        else if (this.string.compareTo(o.getString()) == 0)
            return 0;
        else
            return -1;
    }

}

測試代碼:

package org.vincent.strategy.test;

public class Test {
    public static void main(String[] args) {
        Domain d1 = new Domain("c");
        Domain d2 = new Domain("c");
        Domain d3 = new Domain("b");
        Domain d4 = new Domain("d");
        System.out.println(d1.compareTo(d2));
        System.out.println(d1.compareTo(d3));
        System.out.println(d1.compareTo(d4));
    }
}

輸出:


0
1
-1

實現Comparable接口的類是爲了支持類對象之間是可以比較的,但是其實代碼裏面Comparable的泛型未必就一定要是Domain,將泛型指定爲String或者指定爲其他任何任何類型都可以—-只要我們知道具體的比較類型就行。
比如講Comparable的泛型參數指定爲String,相應compareTo函數變爲:

    public int compareTo(String o) {
        // TODO Auto-generated method stub
        if (this.string.compareTo(o) > 0)
            return 1;
        else if (this.string.compareTo(o) == 0)
            return 0;
        else
            return -1;
    }

但是一般我們不這樣做,泛型參數直接爲我們定義的類Domain
總結:Comparable接口就是用於給類提供默認比較功能的。

Comparator

Comparator可以認爲是是一個外比較器,認爲有兩種情況可以使用實現Comparator接口的方式:

  • 一個對象不支持自己和自己比較(沒有實現Comparable接口),但是又想對兩個對象進行比較;一般同類型對象比較很少實現這個接口。

  • 一個對象實現了Comparable接口,但是開發者認爲compareTo方法中的比較方式並不是自己想要的那種比較方式。Comparator接口更多是實現這個功能。對特定比較需求提供支持。

int compare(T o1, T o2);

Comparator接口裏面有一個compare方法,方法有兩個參數T o1和T o2,是泛型的表示方式,分別表示待比較的兩個對象,方法返回值和Comparable接口一樣是int,有三種情況:

  • 1、o1大於o2,返回1

  • 2、o1等於o2,返回0

  • 3、o1小於o3,返回-1

實例:


package org.vincent.strategy;

import java.util.Comparator;

/**
 * 定義一個按照絕對值排序的比較器
 *
 * @ClassName: AbsComparator
 * @Description: TODO(這裏用一句話描述這個類的作用)
 * @author PengRong
 * @date 2017年3月10日 下午6:06:41
 */
public class AbsComparator implements Comparator {
    public int compare(Object o1, Object o2) {
        int v1 = Math.abs(((Integer) o1).intValue());
        int v2 = Math.abs(((Integer) o2).intValue());
        return v1 > v2 ? 1 : (v1 == v2 ? 0 : -1);
    }
}

測試:

package org.vincent.strategy;

import java.util.Arrays;
import java.util.Random;

public class Test {
    @SuppressWarnings("unchecked")
    public static void main(String[] args) {

        // 產生一個20個隨機整數的數組(有正有負)
        Random rnd = new Random();
        Integer[] integers = new Integer[20];
        for (int i = 0; i < integers.length; i++) {
            integers[i] = new Integer(rnd.nextInt(100) * (rnd.nextBoolean() ? 1 : -1));
        }

        System.out.println("用Integer內置方法排序:也就是Integer實現Comparable接口所描述的比較方法");
        Arrays.sort(integers);
        System.out.println(Arrays.asList(integers));

        System.out.println("用AbsComparator排序:按絕對值大小排序");
        Arrays.sort(integers, new AbsComparator());
        System.out.println(Arrays.asList(integers));
    }
}

輸出結果:

Integer內置方法排序:也就是Integer實現Comparable接口所描述的比較方法
[-88, -82, -82, -78, -70, -70, -58, -58, -48, -48, -46, -35, -10, 4, 7, 19, 39, 45, 53, 85]AbsComparator排序:按絕對值大小排序
[4, 7, -10, 19, -35, 39, 45, -46, -48, -48, 53, -58, -58, -70, -70, -78, -82, -82, 85, -88]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章