如何实现Comparable接口



我们在下面编写了以下Movie类,我们希望能够使用Collections.sort方法对ArrayList<Movie>进行排序。我们希望通过title实例变量进行排序,并通过year实例变量打破联系。然而,我们的代码不起作用,我们也不知道为什么。

示例

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);
}

将打印以下内容:

(Fast Five, 2011)
(Good Burger, 1997)
(The Lord of the Rings: The Fellowship of the Ring, 2001)

这是Movie类:

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);
}
}

如何实现Comparable接口?

实现这一点的一种方法是使用Comparator<T>接口:

return Comparator.comparing(Movie::title)
.thenComparingInt(Movie::year)
.compare(this, m);

您想按title排序,但在compareTo方法中使用了year,如下所示:

@Override
public int compareTo(Movie m) {
return Integer.compare(m1.getYear(), m2.getYear());
}

将其更改为

@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;
}

为了获得更大的灵活性,您可以使用Comparator而不是Comparable,如Java:Comparable vs 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;
}
}

然后使用Collections.sort(movies, new MovieCompartor())而不是Collections.sort(movies)

您必须首先按标题排序,然后按年份排序:

@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
}

最新更新