1. 程式人生 > >Live and Learn

Live and Learn

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