Comparable
是一個比較大小的接口,在比較基本數據類型時可以直接使用>
<
的方式進行比較,但是引用數據類型所存放的是記憶中的地址,所以不能直接使用>
<
比較大小。
以下用Arrays
的sort
方法進行示範
String[] arr = new String[]{"banana", "apple", "orange", "lemon"};
Arrays.sort(arr); // ["apple", "banana", "lemon", "orange"]
印出的值
["apple", "banana", "lemon", "orange"]
假設有這樣的一個類
class Product {
String name;
int price;
public Product(name, price) {
this.name = name;
this.price = price;
}
public int getPrice() {
return price;
}
@Override
public String toString() {
return "Product{" + "name=" + name + '\'' + ", price=" + price + '}';
}
}
進行排序會報錯
:ClassCastException
。Product不能轉換成Comparable
Product[] arr = new Product[4];
arr[0] = new Product("banana", 50);
arr[1] = new Product("apple", 20);
arr[2] = new Product("lemon", 70);
arr[3] = new Product("orange", 30);
Arrays.sort(arr); // ClassCastException
原因在於Product並沒有實作Comparable
這個接口的抽象方法compareTo
。(String本身是有去實作的)
改寫Product
類實作Comparable
class Product implements Comparable {
//...略
@Override
public int compareTo(Object o) {
if(o == this) {
return 0;
}
if(o instanceof Product) {
Product p = (Product) o; // 進行強制轉換類型
if(this.price == p.price) {
return 0;
}
if(this.price > p.price) {
return 1;
}
if(this.price < p.price) {
return -1;
}
}
throw new RuntimeException("類型錯誤");
}
}
再進行一次排序
Product[] arr = new Product[4];
arr[0] = new Product("banana", 50);
arr[1] = new Product("apple", 20);
arr[2] = new Product("lemon", 70);
arr[3] = new Product("orange", 30);
Arrays.sort(arr);
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
印出的值
Product{name='apple', price=20}
Product{name='orange', price=30}
Product{name='banana', price=50}
Product{name='lemon', price=70}
Comparator
是一個比較大小的接口,與Comparable
不同的地方在於,它主要用於當某個類已經有使用Comparable
進行比較的實作,但是無法對它的程式碼進行修改,這時候就需要使用Comparator
。(例如String
中已經有實作Comparable
)
使用方式:需要創建一個實作Comparator
接口的實例,並且將抽象方法compare
實作
Product[] arr = new Product[4];
arr[0] = new Product("banana", 50);
arr[1] = new Product("apple", 20);
arr[2] = new Product("lemon", 70);
arr[3] = new Product("orange", 30);
Comparator comparator = new Comparator(){
@Override
public int compare(Object obj1, Object obj2) {
if(obj1 instanceof Product && obj2 instanceof Product) {
Product p1 = (Product) obj1;
Product p2 = (Product) obj2;
if(p1.getPrice() > p2.getPrice()) {
return 1;
}
if(p1.getPrice() < p2.getPrice()) {
return -1;
}
if(p1.getPrice() == p2.getPrice()) {
return 2;
}
throw new RuntimeException("類型錯誤");
}
}
}
Array.sort(arr, comparator); // sort方法如果傳入第二個參數,會使用該參數的方法去比較
Comparable
compareTo(Object obj)
。(因為是使用類本身的方法,所以只需要將要比較的物件傳入參數中)Comparator
compare(Object obj1, Object obj2)
。(因為使用的是實作Comparator
接口的物件,並非要比較物件,所以必須將兩個要進行比較的物件傳入參數中)