1. 程式人生 > 實用技巧 >Comparable VS Comparator

Comparable VS Comparator

前言

在閱讀TreeMap原始碼時發現了Comparable與Comparator,光是名字看起來就很像,既然都是比較器,那有何區別呢?實際上我對於比較器的使用場景並不是很多,所以這篇還是借鑑了別人的想法。

比較

通過下面的這段程式碼來說明問題。


    public class Test {

        public static void main(String[] args) {
            Apple appleOne = new Apple(1, "red");
            Apple appleTwo = new Apple(2, "green");
            appleOne.compareTo(appleTwo);
        }
    }

    class Apple implements Comparable<Apple> {

        private int size;
        private String color;

        Apple(int size, String color){
            this.size = size;
            this.color = color;
        }

        @Override
        public int compareTo(Apple o) {
            return size > o.size ? 1 : 0; //比較Apple的大小
        }

        //getter、setter
    }

程式碼上挺簡單的,只是比較了Apple的大小,現在來思考一下,哪一天突然想比較Apple的顏色了,那豈不是要改程式碼了,而對於新需求我們通常說現有程式碼儘量保持不變,通過新增類的方式來滿足,所以Comparable的缺點很明顯,一旦某個類指定了比較方式後就無法做修改(除非是修改程式碼...),即使能修改程式碼我們也不知道會不會造成新的問題或新的需求產生,所以這是行不通的。而對於Comparator來說,它就顯得更加靈活了,支援多個比較器,只要新增類即可,看如下的程式碼展示:


    public class Test {

        public static void main(String[] args) {
            Apple appleOne = new Apple(1, "red");
            Apple appleTwo = new Apple(2, "green");

            //比較Apple的大小
            AppleCompareSize acs = new AppleCompareSize();
            acs.compare(appleOne, appleTwo);

            //比較Apple的顏色
            AppleCompareColor acc = new AppleCompareColor();
            acc.compare(appleOne, appleTwo);
        }
    }

    class Apple {

        private int size;
        private String color;

        Apple(int size, String color) {
            this.size = size;
            this.color = color;
        }

        //getter、setter
    }

    class AppleCompareSize implements Comparator<Apple> {

        @Override
        public int compare(Apple o1, Apple o2) {
            return o1.getSize() > o2.getSize() ? 1 : 0;
        }
    }

    class AppleCompareColor implements Comparator<Apple> {

        @Override
        public int compare(Apple o1, Apple o2) {
            return o1.getColor().compareTo(o2.getColor());
        }
    }

應該很容易就能看出效果了,即使別人已經寫好了一個比較器,對於新需求,我們只要增加即可,並不會出現修改或汙染其他人程式碼的情況。

總結

Comparator與Comaparable的最大區別在於Comparator能夠定義多種不同的比較策略,即新增多個比較來,同時避免往比較物件(Apple)中新增其他程式碼(比較)