Comparable和Comparator是Java核心API提供的兩個接口。從它們的名字,我們大致可以猜到它們用來以某種方式比較一些事物。但它們到底是什麼,它們之間有又哪些差別呢?下面的兩個例子回答了這個問題。這個例子用來比較HDTV的大小。閱讀完下面的代碼,對於如何使用Comparable和Comparator會很清楚。
一個類為了能比較自身對象與其他對象實現這個接口。一個類如果要比較自己的實例就必須實現這個接口。而且要實現compareTo()這個方法。示例:
class HDTV implements Comparable{ 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."); } }
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 {
@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 al = new ArrayList();
al.add(tv1);
al.add(tv2);
al.add(tv3);
Collections.sort(al, new SizeComparator());
for (HDTV a : al) {
System.out.println(a.getBrand());
}
}
}
另外,我們還可以使用Collections.reverseOrder()來獲取一個反序比較器。類似於下面:
ArrayListal = new ArrayList (); al.add(3); al.add(1); al.add(2); System.out.println(al); Collections.sort(al); System.out.println(al); Comparator comparator = Collections.reverseOrder(); Collections.sort(al,comparator); System.out.println(al);
簡單來說,一個類實現Comparable接口後會變成比較的,也就是說它的實例之間可以互相比較。
一個類實現了Comparator接口主要用於兩種情況:1)可以傳遞給一個排序方法,像Collections.sort()或者Arrays.sort(),精確地控制排序方式。2)它還可以用來控制特定數據結構的排序,比如TreeSet或者TreeMap等。
例如,創建一個TreeSet,我們或者向其構造器傳遞一個comparator或者實現comparable接口。
實現1(使用comparator)
class Dog {
int size;
Dog(int s) {
size = s;
}
}
class SizeComparator implements Comparator {
@Override
public int compare(Dog d1, Dog d2) {
return d1.size - d2.size;
}
}
public class ImpComparable {
public static void main(String[] args) {
TreeSet d = new TreeSet(new SizeComparator()); // pass comparator
d.add(new Dog(1));
d.add(new Dog(2));
d.add(new Dog(1));
}
}
實現2(使用comparable)
class Dog implements Comparable{ 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 d = new TreeSet (); d.add(new Dog(1)); d.add(new Dog(2)); d.add(new Dog(1)); } }