第21条:用函数对象表示策略

C语言标准库中的qsort函数要求用一个指向comparator函数的指针作为参数,它用这个函数来比较待排序的元素。比较器有两个参数,都是指向元素的指针。通过传递不同的比较器函数,可以获得不同的排列顺序,这是策略模式的一个例子。比较器函数代表一种为元素排序的策略。

 

java.util表中有一个Comparator接口:

public  interface Comparator<T> {
    public int compare(T t1, T t2);
}

这是一个策略接口,具体的策略类实现该接口,因为使用了泛型,所以可以用来比较不同的数据类型。

 

当一个具体的策略类只被使用一次时,通常使用匿名类来声明和实例化这个具体策略类:

Arrays.sort(StringArray, new Comparator<String>() {
    public int compare(String s1, String s2) {
        return s1.length() - s2.length();
    }
});

比较器实现根据字符串的长度来比较。

 

当一个具体策略是设计用力爱重复使用的时候,通常被实现为私有的静态成员类,并通过公有的静态final域被导出:

class Host {
    private static class StrLenCmp implements Comparator<String>, Serializable {
    public int compare(String s1, String s2) {
        return s1.length() - s2.length();
    }
    }
    
    public static final Comparator<String> STRING_LENGTH_COMPARATOR = new StrLenCmp();

}

 

String类利用这种模式,通过它的CASE_INSENSITIVE_ORDER域,导出一个不区分大小写的字符串比较器。

public static final Comparator<String> CASE_INSENSITIVE_ORDER
                                         = new CaseInsensitiveComparator();
    private static class CaseInsensitiveComparator
            implements Comparator<String>, java.io.Serializable {
        // use serialVersionUID from JDK 1.2.2 for interoperability
        private static final long serialVersionUID = 8575799808933029326L;

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

 

posted @ 2016-07-26 22:59  没有梦想的小灰灰  阅读(258)  评论(0编辑  收藏  举报