Comparable和Comparator区别分析

当遇到要对自己构造的类进行比较时,比如当要构造PriorityQueue实现类、TreeSet实现类、TreeMap实现类等等,或者是使用Collections.sort方法时,会需要类实现Comparable接口或者传入Comparator接口的实现类。

Comparable

当我们构造的类实现 java.lang.Comparable 接口时,需要覆写compareTo()方法。String、Integer等类可直接调用compareTo()方法
比如编写一个Movie类,用电影年份进行排序,年份小的优先级更高。

// A Java program to demonstrate use of Comparable 
  
// A class 'Movie' that implements Comparable 
class Movie implements Comparable<Movie> 
{ 
    private double rating; 
    private String name; 
    private int year; 
  
    // Used to sort movies by year 
    public int compareTo(Movie m) 
    { 
        return this.year - m.year; 
    } 
  
    // Constructor 
    public Movie(String nm, double rt, int yr) 
    { 
        this.name = nm; 
        this.rating = rt; 
        this.year = yr; 
    } 
  
    // Getter methods for accessing private data 
    public double getRating() { return rating; } 
    public String getName()   {  return name; } 
    public int getYear()      {  return year;  } 
} 
  
// Driver class 
class Main 
{ 
    public static void main(String[] args) 
    { 
        ArrayList<Movie> list = new ArrayList<Movie>(); 
        list.add(new Movie("Force Awakens", 8.3, 2015)); 
        list.add(new Movie("Star Wars", 8.7, 1977)); 
        list.add(new Movie("Empire Strikes Back", 8.8, 1980)); 
        list.add(new Movie("Return of the Jedi", 8.4, 1983)); 
  
        Collections.sort(list); 
  
        System.out.println("Movies after sorting : "); 
        for (Movie movie: list) 
        { 
            System.out.println(movie.getName() + " " + 
                               movie.getRating() + " " + 
                               movie.getYear()); 
        } 
    } 
} 

Comparator

但如果我还想根据电影评分等信息进行排序,Comparable就做不到了,因为只能覆写一次compareTo方法。于是我们可以编写Comparator的实现类并覆写compare方法来实现多种排序方式。

//A Java program to demonstrate Comparator interface 
  
// Class to compare Movies by ratings 
class RatingCompare implements Comparator<Movie> 
{ 
    public int compare(Movie m1, Movie m2) 
    { 
        if (m1.getRating() < m2.getRating()) return -1; 
        if (m1.getRating() > m2.getRating()) return 1; 
        else return 0; 
    } 
} 
  
// Class to compare Movies by name 
class NameCompare implements Comparator<Movie> 
{ 
    public int compare(Movie m1, Movie m2) 
    { 
        //String类型实现了Comparable接口,即可调用compareTo方法
        return m1.getName().compareTo(m2.getName()); 
    } 
} 
  
// Driver class 
class Main 
{ 
    public static void main(String[] args) 
    { 
        ArrayList<Movie> list = new ArrayList<Movie>(); 
        list.add(new Movie("Force Awakens", 8.3, 2015)); 
        list.add(new Movie("Star Wars", 8.7, 1977)); 
        list.add(new Movie("Empire Strikes Back", 8.8, 1980)); 
        list.add(new Movie("Return of the Jedi", 8.4, 1983)); 
  
        // Sort by rating : (1) Create an object of ratingCompare 
        //                  (2) Call Collections.sort 
        //                  (3) Print Sorted list 
        System.out.println("Sorted by rating"); 
        RatingCompare ratingCompare = new RatingCompare(); 
        Collections.sort(list, ratingCompare); 
        for (Movie movie: list) 
            System.out.println(movie.getRating() + " " + 
                               movie.getName() + " " + 
                               movie.getYear()); 
  
        System.out.println("\nSorted by name"); 
        NameCompare nameCompare = new NameCompare(); 
        Collections.sort(list, nameCompare); 
        for (Movie movie: list) 
            System.out.println(movie.getName() + " " + 
                               movie.getRating() + " " + 
                               movie.getYear()); 
    } 
}

//也可以直接在构造list时传入Comparator的实现类
//不过这样就直接定好了构造的list的排序方式
//在构造PriorityQueue、TreeSet、TreeMap等实现类时,大多用这样写
ArrayList<Movie> list = new ArrayList<Movie>(RatingCompare); 

所以,如果某个类需要多种排序策略,则可用Comparator实现。

你可能感兴趣的:(Java)