Java中的Comparable vs Comparator

Java提供了两个接口来使用类的数据成员对对象进行排序:

null
  1. 可比较的
  2. 比较器

使用可比较的界面

一个可比较的对象能够将自己与另一个对象进行比较。类本身必须实现 JAVA可比的 接口来比较其实例。 考虑一个电影类,有成员,如评级,名称,年。假设我们希望根据发行年份对电影列表进行排序。我们可以用Movie类实现Comparable接口,并重写Comparable接口的compareTo()方法。

JAVA

// A Java program to demonstrate use of Comparable
import java.io.*;
import java.util.*;
// 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());
}
}
}


输出:

Movies after sorting : Star Wars 8.7 1977Empire Strikes Back 8.8 1980Return of the Jedi 8.4 1983Force Awakens 8.3 2015

现在,假设我们想根据电影的等级和名称对电影进行排序。当我们使集合元素具有可比性时(通过让它实现可比性),我们只有一次机会实现compareTo()方法。解决方案是使用 比较器。

使用比较器

与Comparable不同,Comparator位于我们正在比较的元素类型之外。这是一门独立的课。我们创建了多个单独的类(实现Comparator)以供不同的成员进行比较。 Collections类有第二个sort()方法,它使用Comparator。sort()方法调用compare()对对象进行排序。 要通过评级来比较电影,我们需要做三件事:

  1. 创建一个实现Comparator的类(以及完成compareTo()之前所做工作的compare()方法)。
  2. 创建Comparator类的一个实例。
  3. 调用重载的sort()方法,为其提供实现Comparator的类的列表和实例。

JAVA

//A Java program to demonstrate Comparator interface
import java.io.*;
import java.util.*;
// 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;  }
}
// 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)
{
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());
// Call overloaded sort method with RatingCompare
// (Same three steps as above)
System.out.println( "Sorted by name" );
NameCompare nameCompare = new NameCompare();
Collections.sort(list, nameCompare);
for (Movie movie: list)
System.out.println(movie.getName() + " " +
movie.getRating() + " " +
movie.getYear());
// Uses Comparable to sort by year
System.out.println( "Sorted by year" );
Collections.sort(list);
for (Movie movie: list)
System.out.println(movie.getYear() + " " +
movie.getRating() + " " +
movie.getName()+ " " );
}
}


输出:

Sorted by rating8.3 Force Awakens 20158.4 Return of the Jedi 19838.7 Star Wars 19778.8 Empire Strikes Back 1980Sorted by nameEmpire Strikes Back 8.8 1980Force Awakens 8.3 2015Return of the Jedi 8.4 1983Star Wars 8.7 1977Sorted by year1977 8.7 Star Wars 1980 8.8 Empire Strikes Back 1983 8.4 Return of the Jedi 2015 8.3 Force Awakens

  • Comparable是指具有自然顺序的对象,这意味着对象本身必须知道如何进行排序。例如,滚动学生人数。然而,比较器接口排序是通过一个单独的类完成的。
  • 从逻辑上讲,Comparable接口将“this”引用与指定的对象进行比较,Java中的Comparator将比较提供的两个不同的类对象。
  • 如果有任何类在Java中实现了可比较的接口,那么可以使用集合对该对象的集合(列表或数组)进行自动排序。sort()或数组。sort()方法和对象将根据CompareTo方法定义的自然顺序进行排序。
  • 一个基本的区别特征是,使用comparable,我们只能使用一个比较。然而,对于给定类型,我们可以根据需要编写多个自定义比较器,所有这些都使用对排序含义的不同解释。就像在可比较的例子中,我们只能按一个属性进行排序,即年份,但在比较中,我们也可以使用不同的属性,如评级、名称和年份。

总之,如果需要根据自然顺序对对象进行排序,那么使用Comparable;如果需要对不同对象的属性进行排序,那么使用Java中的Comparator。

本文由 苏拉迪普·巴鲁阿。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享