1. 程式人生 > >java lang(Comparable接口) 和java util(Comparator接口)分析比較

java lang(Comparable接口) 和java util(Comparator接口)分析比較

比較 inter add 自動 bject ret 動態 clas ons

//Comparable 接口強行對實現它的每個類的對象進行整體排序。 -- 自然排序。類的compareTo稱為自然比較方法。

public interface Comparable<T> {
    public int compareTo(T o);
}

  此接口強行對實現它的每個類的對象進行整體排序。這種排序被稱為類的自然排序,類的 compareTo 方法被稱為它的自然比較方法

  實現此接口的對象列表(和數組)可以通過 Collections.sort(和 Arrays.sort)進行自動排序。實現此接口的對象可以用作有序映射(接口 java.util.SortedMap<K,V>)中的鍵或有序集合(接口 java.util.SortedSet<E>)中的元素,無需指定比較器(接口 java.util.Comparator<T>)。

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

  1. e1.compareTo(e2) > 0 即 e1 > e2
  2. e1.compareTo(e2) = 0 即 e1 = e2
  3. e1.compareTo(e2) < 0 即 e1 < e2

註意:

1.由於 null 不是一個類,也不是一個對象,因此在重寫 compareTo 方法時應該註意 e.compareTo(null) 的情況,即使 e.equals(null) 返回 false,compareTo 方法也應該主動拋出一個空指針異常 NullPointerException。

2.Comparable 實現類重寫 compareTo 方法時一般要求 e1.compareTo(e2) == 0 的結果要和 e1.equals(e2) 一致。這樣將來使用 SortedSet 等根據類的自然排序進行排序的集合容器時可以保證保存的數據的順序和想象中一致。

接口實現的例子:

import java.util.ArrayList;
import java.util.Collections;

public class Car implements Comparable<Object>{
	public String name;
	public int price;
	
	public Car(String name, int price){
		this.name = name;
		this.price = price;
	}
	
	public String toString() {
		return this.name + ":" + this.price;
	}
	
	@Override
	public int compareTo(Object o) {
		if ( o instanceof Car) {
			Car  car = (Car)o;
			int result;
			
			result = this.price - car.price;
//			當car的price相同時,比較其name,按String的comparaTo()方法排序
			if (result == 0) {
				result = this.name.compareTo(car.name);
			}
			return result;
		}
		return 0;
	}
	
	public static void main(String[] args) {
		ArrayList<Car> all = new ArrayList<Car>();
		all.add(new Car("蘭博基尼", 400));
		all.add(new Car("寶馬", 100));
		all.add(new Car("奔馳", 95));
		all.add(new Car("法拉利", 300));
		
		System.out.println(all);
		Collections.sort(all);
		System.out.println(all);
	}

}

打印出:

[蘭博基尼:400, 寶馬:100, 奔馳:95, 法拉利:300]
[奔馳:95, 寶馬:100, 法拉利:300, 蘭博基尼:400]

Comparator 比較器接口(策略設計模式)

  我們如果需要控制某個類的次序,而該類本身不支持排序(即沒有實現Comparable接口);那麽可以建立一個該類的比較器來排序,這個比較器只需要實現Comparator接口即可。

public interface Comparator<T> {
     int compare(T o1, T o2);
     boolean equals(Object obj);
}

使用方式主要分三步:

1.創建一個 Comparator 接口的實現類,並賦值給一個對象在 compare 方法中針對自定義類寫排序規則

2.將 Comparator 對象作為參數傳遞給 排序類的某個方法

3.向排序類中添加 compare 方法中使用的自定義類

接口操作例子:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Car {
	public String name;
	public int price;
	
	public Car(String name, int price){
		this.name = name;
		this.price = price;
	}
	
	public String toString() {
		return this.name + ":" + this.price;
	}
	public static void main(String[] args) {
		ArrayList<Car> all = new ArrayList<Car>();
		all.add(new Car("蘭博基尼", 400));
		all.add(new Car("寶馬", 100));
		all.add(new Car("奔馳", 95));
		all.add(new Car("法拉利", 300));
		
		System.out.println(all);
		Collections.sort(all, new MyComparator());
		System.out.println(all);	
		
	}

}

class MyComparator implements Comparator<Car> {

	@Override
	public int compare(Car o1, Car o2) {
		// TODO Auto-generated method stub
		int result = o1.price - o2.price;
		if ( result != 0) {
			return result;
		} else {
			return o1.name.compareTo(o2.name);
		}
	}
	
}

打印出:

[蘭博基尼:400, 寶馬:100, 奔馳:95, 法拉利:300]
[奔馳:95, 寶馬:100, 法拉利:300, 蘭博基尼:400]

Comparable 和 Comparator比較

Comparable 是排序接口;若一個類實現了 Comparable 接口,就意味著 “該類支持排序”。
而 Comparator 是比較器;我們若需要控制某個類的次序,可以建立一個 “該類的比較器” 來進行排序。

前者應該比較固定,和一個具體類相綁定,而後者比較靈活,它可以被用於各個需要比較功能的類使用。可以說前者屬於 “靜態綁定”,而後者可以 “動態綁定”。

我們不難發現:Comparable 相當於 “內部比較器”,而 Comparator 相當於 “外部比較器”。

java lang(Comparable接口) 和java util(Comparator接口)分析比較