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)); } }