[英]How to implement the Comparable interface?
We have written the following Movie
class below, and we want to be able to use the Collections.sort
method to sort an ArrayList<Movie>
.我们在下面编写了以下Movie
class,我们希望能够使用Collections.sort
方法对ArrayList<Movie>
进行排序。 We want to sort by the title
instance variable, and we want to break ties by the year
instance variable.我们想要按title
实例变量排序,并且我们想要按year
实例变量打破平局。 However, our code doesn't work, and we have no idea why.但是,我们的代码不起作用,我们也不知道为什么。
Example例子
ArrayList<Movie> movies = new ArrayList<>();
movies.add(new Movie("Good Burger", 1997));
movies.add(new Movie("The Lord of the Rings: The Fellowship of the Ring", 2001));
movies.add(new Movie("Fast Five", 2011));
Collections.sort(movies);
for (Movie m : movies) {
System.out.println(m);
}
will print the following:将打印以下内容:
(Fast Five, 2011)
(Good Burger, 1997)
(The Lord of the Rings: The Fellowship of the Ring, 2001)
This is the Movie
class:这是Movie
class:
class Movie implements Comparable<Movie> {
private final String title;
private final int year;
public Movie(String t, int y) {
this.title = t;
this.year = y;
}
public String toString() {
return "(" + this.title + ", " + this.year + ")";
}
public boolean equals(Object o) {
return (o instanceof Movie) && // check if o is a Movie
this.year == ((Movie)o).year && // check years for equality
this.title.equals(((Movie)o).title); // check titles for equality
}
@Override
public int compareTo(Movie m) {
return Integer.compare(this.year, m.year);
}
}
How does one implement the Comparable
interface?如何实现Comparable
接口?
One way to do this is to use the Comparator<T>
interface:一种方法是使用Comparator<T>
接口:
return Comparator.comparing(Movie::title)
.thenComparingInt(Movie::year)
.compare(this, m);
You want to sort by the title
, but you have used year
in your compareTo
method as follows:您想按title
排序,但您在compareTo
方法中使用了year
,如下所示:
@Override
public int compareTo(Movie m) {
return Integer.compare(m1.getYear(), m2.getYear());
}
Change it to将其更改为
@Override
public int compareTo(Movie m) {
int c;
if(this.title!=null && m!=null && m.getTitle()!=null){
c = this.title.compareTo(m.getTitle());
if (c == 0)
c = Integer.compare(this.year, m.getYear());
}
return c;
}
For more flexibility, you can use Comparator
instead of Comparable
as discussed at Java: Comparable vs Comparator为了获得更大的灵活性,您可以使用Comparator
而不是Comparable
,如Java 中所述:Comparable vs Comparator
Update: I just went through your question again and realized that first, you want to compare the title and then in case of a tie, you want to compare on year.更新:我刚刚再次查看了您的问题,并意识到首先,您想比较标题,然后在平局的情况下,您想比较年份。 I have updated the code given above.我已经更新了上面给出的代码。 Additionally, I have provided another approach (using Comparator) below:此外,我在下面提供了另一种方法(使用 Comparator):
public class MovieCompartor implements Comparator<Movie>{
public int compare(Movie m1, Movie m2) {
int c;
if(m!=null && m2!=null){
if(m1.getTitle()!=null && m2.getTitle()!=null)
c = m1.getTitle().compareTo(m2.getTitle());
if (c == 0)
c = Integer.compare(m1.getYear(), m2.getYear());
}
return c;
}
}
Then you use Collections.sort(movies, new MovieCompartor())
instead of Collections.sort(movies)
.然后你使用Collections.sort(movies, new MovieCompartor())
而不是Collections.sort(movies)
。
You have to first sort by title, then sort by year:您必须首先按标题排序,然后按年份排序:
@Override
public int compareTo(Movie m){
if (this.title.equals(m.title)){ //if titles are same
return this.year - m.year; //compare years
}
return this.title.compareTo(m.title); //else just compare titles
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.