JavaJava 杂谈

Comparable vs. Comparator in Jav

2018-04-23  本文已影响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

上一篇下一篇

猜你喜欢

热点阅读