Java8 Comparator - Detailed explanation of how to sort a List
In this article, we will see a few details on how to sort a List in Java 8 example of.
List<String> cities = Arrays.asList( "Milan", "london", "San Francisco", "Tokyo", "New Delhi" ); System.out.println(cities); //[Milan, london, San Francisco, Tokyo, New Delhi] cities.sort(String.CASE_INSENSITIVE_ORDER); System.out.println(cities); //[london, Milan, New Delhi, San Francisco, Tokyo] cities.sort(Comparator.naturalOrder()); System.out.println(cities); //[Milan, New Delhi, San Francisco, Tokyo, london]
London's "L" uses lowercase letters to better highlight Comparator.naturalOrder() (returns sorting uppercase first The difference between a comparator for letters) and String.CASE_INSENSITIVE_ORDER (a comparator that returns case-insensitive).
Basically, in Java 7, we used Collection.sort() which accepts a List and finally a Comparator - in Java 8, we have the new List.sort() which accepts a Comparator.
List<Integer> numbers = Arrays.asList(6, 2, 1, 4, 9); System.out.println(numbers); //[6, 2, 1, 4, 9] numbers.sort(Comparator.naturalOrder()); System.out.println(numbers); //[1, 2, 4, 6, 9]
Suppose we have a Movie class, and we want to "by title title" "Sort the List. We can use Comparator.comparing() , passing a function that extracts the field used to sort title - in this case.
List<Movie> movies = Arrays.asList( new Movie("Lord of the rings"), new Movie("Back to the future"), new Movie("Carlito's way"), new Movie("Pulp fiction")); movies.sort(Comparator.comparing(Movie::getTitle)); movies.forEach(System.out::println);
Output:
Movie{title='Back to the future'} Movie{title='Carlito's way'} Movie{title='Lord of the rings'} Movie{title='Pulp fiction'}
Maybe you will notice that we are not passing any Comparator, but the List is sorted correctly. This is because title - the extracted field - is a string, and strings implement the Comparable interface . If you look at the Comparator.comparing() implementation, you'll see that it calls compareTo on the extracted key.
return (Comparator<T> & Serializable) (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
In a similar way, we can use Comparator.comparingDouble() to compare double values. In the example, we want to order a list of Movies from highest to lowest rating.
List<Movie> movies = Arrays.asList( new Movie("Lord of the rings", 8.8), new Movie("Back to the future", 8.5), new Movie("Carlito's way", 7.9), new Movie("Pulp fiction", 8.9)); movies.sort(Comparator.comparingDouble(Movie::getRating) .reversed()); movies.forEach(System.out::println);
We use the reversed function on the Comparator in order to reverse the default natural order from lowest to highest. Comparator.comparingDouble() uses Double.compare() internally.
If you need to compare int or long, then you can use comparingInt() and comparingLong() respectively.
In the previous example, we did not specify any comparator because it was not necessary, but let us look at an example in which we defined our own comparator. Our Movie class has a new field - "starred" - set using the third constructor parameter. In the example, we want to sort the list so that the starred movies are at the top of the list.
List<Movie> movies = Arrays.asList( new Movie("Lord of the rings", 8.8, true), new Movie("Back to the future", 8.5, false), new Movie("Carlito's way", 7.9, true), new Movie("Pulp fiction", 8.9, false)); movies.sort(new Comparator<Movie>() { @Override public int compare(Movie m1, Movie m2) { if(m1.getStarred() == m2.getStarred()){ return 0; } return m1.getStarred() ? -1 : 1; } }); movies.forEach(System.out::println);
The result will be:
Movie{starred=true, title='Lord of the rings', rating=8.8} Movie{starred=true, title='Carlito's way', rating=7.9} Movie{starred=false, title='Back to the future', rating=8.5} Movie{starred=false, title='Pulp fiction', rating=8.9}
We can of course use lambdaexpression instead of the Anonymous class as follows:
movies.sort((m1, m2) -> { if(m1.getStarred() == m2.getStarred()){ return 0; } return m1.getStarred() ? -1 : 1; });
We can also Using Comparator.comparing() again:
movies.sort(Comparator.comparing(Movie::getStarred, (star1, star2) -> { if(star1 == star2){ return 0; } return star1 ? -1 : 1; }));
In the latest example, Comparator.comparing() takes the first argument as a function that extracts the key used for sorting, and the Comparator as the second argument. Comparator uses extracted keys for comparison, star1 and star2 are really boolean values, representing m1.getStarred() and m2.getStarred() respectively.
In the last example, we want to add the starred movies at the top and then sort by rating.
List<Movie> movies = Arrays.asList( new Movie("Lord of the rings", 8.8, true), new Movie("Back to the future", 8.5, false), new Movie("Carlito's way", 7.9, true), new Movie("Pulp fiction", 8.9, false)); movies.sort(Comparator.comparing(Movie::getStarred) .reversed() .thenComparing(Comparator.comparing(Movie::getRating) .reversed()) ); movies.forEach(System.out::println);
The output is:
Movie{starred=true, title='Lord of the rings', rating=8.8} Movie{starred=true, title='Carlito's way', rating=7.9} Movie{starred=false, title='Pulp fiction', rating=8.9} Movie{starred=false, title='Back to the future', rating=8.5}
As you can see, we sort by stars first and then by rating - both are reversed because we want the highest value and a true first.
The above is the detailed content of Java8 comparator-detailed explanation of how to sort List. For more information, please follow other related articles on the PHP Chinese website!