Reputation: 1369
Can some one explain the difference between following variants of complex Comparator
s?
List<String> listOfStrings = Arrays.asList("algo", "test", "is", "a", "common");
listOfStrings.stream()
.sorted(Comparator.comparingInt(String::length).thenComparing(Comparator.naturalOrder()))
.sorted(Comparator.naturalOrder().thenComparing(Comparator.comparingInt(String::length))
.forEach(System.out::println);
Why first call of sorted
is OK, while second one can not even compile?
Upvotes: 3
Views: 1920
Reputation: 394156
The compiler knows that Comparator.comparingInt(String::length)
returns a Comparator<String>
(since you are passing a ToIntFunction<String>
to it), and therefore expects the second Comparator
, passed to thenComparing
, to be a Comparator<String>
, so it can infer the type of the Comparator
returned by Comparator.naturalOrder()
to be a Comparator<String>
.
On the other hand, when the first Comparator
is returned by Comparator.naturalOrder()
(which returns a Comparator<T>
), the compiler doesn't know which type of Comparator
to expect for the argument of thenComparing
, so it rejects the Comparator<String>
passed to it.
This error can be avoided if you declare the type of the Comparator
returned by Comparator.naturalOrder()
explicitly:
Comparator<String> comp = Comparator.naturalOrder();
listOfStrings.stream()
.sorted(comp.thenComparing(Comparator.comparingInt(String::length)))
.forEach(System.out::println);
Upvotes: 6
Reputation: 747
Accepts a function that extracts an int sort key from a type T, and returns a Comparator that compares by that sort key.
Returns a comparator that compares Comparable objects in natural order.
You can check natural order from there; difference between natural ordering and total ordering
Comparator API; https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#naturalOrder--
Upvotes: 2