Search code examples
javacomparecomparatorcomparablecompareto

Collection sort that sort based on class that implements Comparator


I have a problem with Collections sorting, to be more specific

Output:
[B_Author: Movie_X, A_Author: Movie_A, A_Author: Movie_B]
Should Be:
[A_Author: Movie_A, A_Author: Movie_B, B_Author: Movie_X]

method thats supposed to do that (in class MovieStorage):

public Set<Movie> getCatalogue(Comparator<Movie> comp){
        List<Movie> sett = new ArrayList<>(this.movieList);
        sett.sort(comp);
        return new HashSet<>(sett);
    }

Class that implements comparator:

public class MovieComparator implements Comparator<Movie>
{
    @Override
    public int compare(Movie a, Movie b) {
        if (a.getName().compareTo(b.getName()) == 0){
            return a.getAuthor().compareTo(b.getAuthor());
        }
        return a.getName().compareTo(b.getName());
    }
}

called method:

System.out.println(movieStorage.getCatalogue(new MovieComparator()));

I have been looking around StackOverflow and other webs, but I have noticed that everyone sorts it based on 1 parameter ( which doesnt work for me too ) and at a same time, the code is pretty much the same as mine is ...

Thanks for help in advance :)


Solution

  • A more compact way to create comparators:

    Comparator<Movie> comparator =
        Comparator.comparing(Movie::getName).thenComparing(Movie::getAuthor);
    
    Set<Movie> movies = new TreeSet<>(comparator);
    movies.addAll(movieList);
    

    And TreeSet iterates in sorted order.

    To add to the Movie class:

    public static class Movie implements Comparable<Movie> {
        private static final Comparator<Movie> COMPARATOR =
            Comparator.comparing(Movie::getName).thenComparing(Movie::getAuthor);
    
        ...
    
        @Override
        public int compareTo(Movie other) {
            return COMPARATOR.compare(this, other);
        }
    }
    

    Then the TreeSet doesn't need a comparator specified:

    Set<Movie> movies = new TreeSet<>(movieList);