Live and Learn
阿新 • • 發佈:2019-02-12
Java 陣列的工具類 Arrays 中的排序方法是典型的應用了策略模式的例示。其定義如下:
public static <T> void sort(T[] a, Comparator<? super T> c){
//...
}
意義是,按照給定的策略執行(Comparator)對陣列進行排序。sort 方法是要做的事情,T[] a 這個陣列是策略作用的物件,Comparator策略本身。其中 Comparator 是一個泛型介面,所有實現了策略介面的具體策略都可以作為引數傳入。Comparator 使用萬用字元,允許利用 T 的超類的策略對 T 進行操作。例如我們有一個書類如下。
public class Book {
private double price;
public Book(double price){
this.price = price;
}
public double getPrice() {
return price;
}
}
我們利用 sort 演算法為其排序時,可以自行選擇排序的依據,即策略。
public class StrategyTest {
@Test
public void test() {
Book[] books = new Book[]{new Book(10.00), new Book(8.70), new Book(12.35), new Book(35.50), new Book(12.35)
};
//排序策略 1: 按照書的價格升序排列
Arrays.sort(books, new Comparator<Book>(){
@Override
public int compare(Book o1, Book o2) {
return Double.compare(o1.getPrice(), o2.getPrice());
}
});
System.out .println("排序策略 1: 按照書的價格升序排列");
for(Book book : books){
System.out.print(book.getPrice() + "\t");
}
//排序策略 2: 按照書的價格降序排列
Arrays.sort(books, new Comparator<Book>(){
@Override
public int compare(Book o1, Book o2) {
return Double.compare(o2.getPrice(), o1.getPrice());
}
});
System.out.println("排序策略 2: 按照書的價格降序排列");
for(Book book : books){
System.out.print(book.getPrice() + "\t");
}
}
}
這裡採用了匿名內部類來提供策略,實際應用當中,策略也常常作為既定的處理方式提供給使用者選擇。例如 String 類中提供了大小寫不敏感的排序策略。
public static final Comparator<String> CASE_INSENSITIVE_ORDER
= new CaseInsensitiveComparator();
private static class CaseInsensitiveComparator
implements Comparator<String>, java.io.Serializable {
public int compare(String s1, String s2) {
int n1 = s1.length();
int n2 = s2.length();
int min = Math.min(n1, n2);
for (int i = 0; i < min; i++) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
if (c1 != c2) {
c1 = Character.toUpperCase(c1);
c2 = Character.toUpperCase(c2);
if (c1 != c2) {
c1 = Character.toLowerCase(c1);
c2 = Character.toLowerCase(c2);
if (c1 != c2) {
// No overflow because of numeric promotion
return c1 - c2;
}
}
}
}
return n1 - n2;
}
/** Replaces the de-serialized object. */
private Object readResolve() { return CASE_INSENSITIVE_ORDER; }
}
Java 集合的工具類 Collections 也提供了類似的 sort 方法。一般地,需要排序的類也會通過實現 Comparable 介面提供一種預設的自然排序方法,而當自然排序不能滿足需求時,才需要使用 Comparator 策略。另外 Collections 也提供了一個逆自然排序方法的策略。對於實現了 Comparable 介面的類,在對其進行排序時,可以使用 Collections 提供的逆序排序策略。
// 按照 arrayOfComparable (實現了 Comparable 介面) 自然排序
Arrays.sort(arrayOfComparable);
// 按照 arrayOfComparable 自然排序演算法逆序排序
Arrays.sort(arrayOfComparable, Collections.reverseOrder());