美文网首页JavaJava 杂谈
Comparable vs. Comparator in Jav

Comparable vs. Comparator in Jav

作者: 打铁大师 | 来源:发表于2018-04-23 13:01 被阅读4次

    原文请戳这里 Comparable vs. Comparator in Java

    ComparableComparator是Java Core API 提供的两个接口。从名字,我们可以知道,他们利用某种方式来比较两个对象。但是,他们到底是什么,他们之间到底有什么区别?这两个例子会回答这个问题。阅读完下面的代码,你将对如何使用 Comparable vs. Comparator有清晰的认识。

    Comparable

    Comparable是由类实现的,目的是为了能够使类自身的对象与其他对象进行比较。为了使它的实例对象能相互比较,类必须实现这个接口。需要实现CompareTo()方法。下面是个例子:

    class HDTV implements Comparable<HDTV> {
      private int size;
      private String brand;
    
      public HDTV(int size, String brand) {
          this.size = size;
          this.brand = brand;
      }
    
      public int getSize() {
          return size;
      }
    
      public void setSize(int size) {
        this.size = size;
      }
    
       public String getBrand() {
         return brand;
       }
    
      public void setBrand(String brand) {
        this.brand = brand;
      }
    
      @Override
      public int compareTo(HDTV tv) {
    
        if (this.getSize() > tv.getSize())
            return 1;
        else if (this.getSize() < tv.getSize())
            return -1;
        else
            return 0;
      }
    }
    
    public class Main {
        public static void main(String[] args) {
            HDTV tv1 = new HDTV(55, "Samsung");
            HDTV tv2 = new HDTV(60, "Sony");
    
            if (tv1.compareTo(tv2) > 0) {
              System.out.println(tv1.getBrand() + " is better.");
            } else {
            System.out.println(tv2.getBrand() + " is better.");
          }
        }
    }
    

    结果:Sony is better.

    Comparator

    在某些情况下,你或许不想去修改类来实现Comparable接口。在这种情况下,如果你想要根据attribute/fields来比较对象,可以使用Comparator。举个例子,2个person可以根据'height'或'age'进行比较。

    需要实现compare()方法。现在,我们换个方式利用size去比较这些TV。Comparator一个通用的用法是进行排序。CollectionsArrays类都提供了利用Comparator进行排序的方法。

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    
    class HDTV {
        private int size;
        private String brand;
    
         public HDTV(int size, String brand) {
            this.size = size;
            this.brand = brand;
         }
    
         public int getSize() {
             return size;
             }
    
         public void setSize(int size) {
           this.size = size;
         }
    
         public String getBrand() {
           return brand;
        }
    
        public void setBrand(String brand) {
            this.brand = brand;
        }
      }
    
    class SizeComparator implements Comparator<HDTV> {
        @Override
        public int compare(HDTV tv1, HDTV tv2) {
            int tv1Size = tv1.getSize();
            int tv2Size = tv2.getSize();
    
            if (tv1Size > tv2Size) {
                return 1;
            } else if (tv1Size < tv2Size) {
              return -1;
            } else {
                return 0;
            }
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            HDTV tv1 = new HDTV(55, "Samsung");
            HDTV tv2 = new HDTV(60, "Sony");
            HDTV tv3 = new HDTV(42, "Panasonic");
    
            ArrayList<HDTV> al = new ArrayList<HDTV>();
            al.add(tv1);
            al.add(tv2);
            al.add(tv3);
    
            Collections.sort(al, new SizeComparator());
            for (HDTV a : al) {
                System.out.println(a.getBrand());
            }
        }
    }
    

    输出:

    Panasonic
    Samsung
    Sony
    

    经常我们会使用Collections.reverseOrder()方法来得到一个降序比较器。就像下面的例子:

     ArrayList<Integer> al = new ArrayList<Integer>();
     al.add(3);
     al.add(1);
     al.add(2);
     System.out.println(al);
     Collections.sort(al);
     System.out.println(al);
    
     Comparator<Integer> comparator =   Collections.reverseOrder();
     Collections.sort(al,comparator);
     System.out.println(al);
    

    输出:

    [3,1,2]
    [1,2,3]
    [3,2,1]
    

    如何选择使用哪个?

    简单来说,一个类如何实现了Comparable将会变得可比较的,这意味着它的实例之间可以相互比较。

    一个类需要实现Comparator,主要在以下两种情境下:

    1. 它会被传递给一个排序方法,比如Collections.sort()Arrays.sort,以便精确控制排序。

    2. 它会被用来控制某些数据结构的排序,比如一个排序的sets(比如:TreeSet)或一个排序maps(比如:TreeMap)

    举个例子: 创建一个TreeSet,我们可以传递一个实现了Comparator的构造函数,也可以使对象类可比较。

    方法1 - TreeSet(Comparator comparator)

    class Dog {
        int size;
    
        Dog(int s) {
            size = s;
        }
    }
    
    class SizeComparator implements Comparator<Dog> {
        @Override
        public int compare(Dog d1, Dog d2) {
            return d1.size - d2.size;
        }
    }
    
    public class ImpComparable {
        public static void main(String[] args) {
            TreeSet<Dog> d = new TreeSet<Dog>(new SizeComparator()); // pass comparator
            d.add(new Dog(1));
            d.add(new Dog(2));
            d.add(new Dog(1));
        }
    }
    

    方法二 - Implement Comparable

    class Dog implements Comparable<Dog>{
        int size;
    
        Dog(int s) {
            size = s;
        }
    
        @Override
        public int compareTo(Dog o) {
             return o.size - this.size;
        }
    }
    
    public class ImpComparable {
        public static void main(String[] args) {
          TreeSet<Dog> d = new TreeSet<Dog>();
          d.add(new Dog(1));
          d.add(new Dog(2));
          d.add(new Dog(1));
        }
    }  
    

    参考文献:
    1.Comparable
    2.Comparator

    相关文章

      网友评论

        本文标题:Comparable vs. Comparator in Jav

        本文链接:https://www.haomeiwen.com/subject/gcbklftx.html