JAvaでのComparableとComparatorの比較

10763 ワード

ComparableとComparatorの比較
  • 両方ともインターフェース
  • である.
  • Comparable
  • はこのインタフェースを継承し、インタフェースを実現する方法(カスタムソート規則)は、「このクラスはソートをサポートする」
  • を表す.
  • は「内部比較」
  • に相当する.
  • あるクラスがこのインタフェースを実現する場合、Arrasysを通過することができる.sort()クラスの配列を
  • 並べ替える
  • このクラスが容器(List,Set)に入ればCollectionsを用いることができる.sort()ソート
  • Comparato
  • はコンパレータの意味で、器はツールに相当し、あるクラスがこのインタフェースを実現すれば比較のルールがある
  • がある.
  • は「外部比較」
  • に相当する.

    a.Comparableインタフェース
    例**
    /**
     * @author bigguy_hc
     * @create 2018-09-03 11:32
     */
    public class Person implements Comparable<Person>{  //     ,    
        int age;
        int score;
    
        public Person(){}
    
        public Person(int age,int score){
            this.age = age;
            this.score = score;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public int getScore() {
            return score;
        }
    
        public void setScore(int score) {
            this.score = score;
        }
        @Override
        public String toString() {
            return "Person{" +
                    "age=" + age +
                    ", score=" + score +
                    '}';
        }
    
        @Override
        //     ,       ,         ,
        public int compareTo(com.bigguy.Person o) {     
            return this.getAge()-o.getAge();
        }
    }

    テストsort()
    //      
    public void test2(){
    
            Person []pers ={new Person(23,91),new Person(21,85),new Person(24,100)};
    
     //             Comparable   ,      Person   compareTo()       
    
            Arrays.sort(pers);         
            for (Person per : pers) {
                System.out.println(per);
            }
        }

    しゅつりょく
    Person{age=21, score=85}
    Person{age=23, score=91}
    Person{age=24, score=100}

    Collectionsをテストします.sort()
    public void test2(){
    
            Person []pers ={new Person(23,91),new Person(21,85),new Person(24,100)};
    
            List list = Arrays.asList(pers);
    
            Collections.sort(list);             //               compareTo()  
    
            for (Person person : list) {
                System.out.println(person);
            }
        }

    しゅつりょく
    Person{age=21, score=85}
    Person{age=23, score=91}
    Person{age=24, score=100}

    b.comparatorインタフェース
    上記のコードに従って(personがComparableインタフェースを実現し、対応する方法を書き直す)
    この場合、需要が変更され、scoreで大きいものから小さいものにソートする必要があります.personの元のコードを変更しないで、コンパレータクラスをカスタマイズする必要があります.
    class PersonScoreComparator implements Comparator{
        public int compare(Person o1, Person o2) {
            return o2.getScore()-o1.getScore();
        }
    }
    
     public void testComparator(){
    
         Person []pers ={new Person(23,91),new Person(21,85),new Person(24,100)};
    
         List list = Arrays.asList(pers);
    
         //          ,          
         Collections.sort(list,new PersonScoreComparator());
    
         for (Person person : list) {
             System.out.println(person);
         }
     }
    /*  :
        Person{age=24, score=100}
        Person{age=23, score=91}
        Person{age=21, score=85}
    */
      :
                 ,       ,          :
    
        public int compare(Person o1, Person o2) {
            return o2.getScore()-o1.getScore();     //   o2 - o1       ->  
        }

    c.まとめ
    Comparatorは柔軟性が高く、比較的疲れた元のコードを修正せず、クラスをカスタマイズして書き換えることができますが、面倒です.
    Comparableは簡単で柔軟性が悪く、変更が必要な場合は元のコードを変更する必要があります
    d. Arrays.sort()とCollections.sort()のjdkソースコード
    Arrays.sort()
    public static void sort(Object[] a) {
        if (LegacyMergeSort.userRequested)
            legacyMergeSort(a);
        else
            ComparableTimSort.sort(a, 0, a.length, null, 0, 0);
    }

    Collections.sort()入力コンパレータなし
     public static super T>> void sort(List list) {
         list.sort(null);       //    null           null
     }
    
    default void sort(Comparator super E> c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }
    
    public static  void sort(T[] a, Comparator super T> c) {
        if (c == null) {        //        null ,    sort(a)
            sort(a);
        } else {
            if (LegacyMergeSort.userRequested)
                legacyMergeSort(a, c);
            else
                TimSort.sort(a, 0, a.length, c, null, 0, 0);
        }
    }

    Collections.sort()入力コンパレータ
     public static  void sort(List list, Comparator super T> c) {
         list.sort(c);
     }
    //                   ,          
    default void sort(Comparator super E> c) {    
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }

    まとめ:
    Arrays.sort()とCollections.sort()まず比較器に入力されたか否かを判断する
    入力コンパレータがコンパレータのルールで比較された場合
    そうでなければComparableインタフェースが実装されている場合は,書き換えcompareTo()メソッド規則に従って比較する.
    そうでなければ、比較するとエラーが表示されます(中の要素は比較性がありません)