4

What is the difference between Comparator::reverseOrder and Comparator.reverseOrder() when used in sorted method of stream.

    Stream<String> streamText = Stream.of("over the river", "through the woods", "to grandmother's house we go");

This works:

    streamText.filter(n -> n.startsWith("t"))
         .sorted(Comparator.reverseOrder())
         .findFirst().ifPresent(System.out::println);

But this does not compile:

    streamText.filter(n -> n.startsWith("t"))
         .sorted(Comparator::reverseOrder)
         .findFirst().ifPresent(System.out::println);
Stuart Marks
  • 127,867
  • 37
  • 205
  • 259
Oro
  • 59
  • 3
  • 3
    [`sorted`](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#sorted-java.util.Comparator-) accepts a `Comparator` as its argument. [`Comparator::reverseOrder`](https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#reverseOrder--) is not a comparator. It is a method that _returns_ a comparator. So you need to call it and pass the return value to `sorted`. – khelwood Apr 19 '18 at 08:16
  • 2
    One is a method invocation and the other is a method reference. They're not interchangeable. It would help if you could explain why you think that `sorted(Comparator::reverseOrder)` should be able to compile. – Erwin Bolwidt Apr 19 '18 at 08:22

1 Answers1

9

Good question!

sorted need a Comparator<T>, right? Comparator<T> is a functional interface. It represents a function that takes 2 arguments and returns an int indicating which argument is greater or whether they are equal.

In the case of Comparator.reverseOrder(), reverseOrder is a method that returns a Comparator<T>. In this case you call the method and it returns a Comparator that can be used as the parameter for sorted. Everything is good.

In the case of Comparator::reverseOrder, you are not calling reverseOrder. Instead, you are passing reverseOrder as a function into sorted. As mentioned above, sorted will accept a function that takes 2 parameters and returns an int, but you are giving it reverseOrder, which takes no arguments and returns a Comparator<T>. See the mismatch here?

Expected: a function that takes 2 parameters and returns an int OR a Comparator<T> object

What you gave it: a function that takes no parameters and returns a Comparator<T>

This results in a compiler error.

Community
  • 1
  • 1
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • Thank you very much for explaining. :). I got it. :: is a method reference and the other is a method call. https://stackoverflow.com/questions/20001427/double-colon-operator-in-java-8 – Oro Apr 19 '18 at 08:47
  • Very well explained! :) – mark42inbound Apr 19 '18 at 10:23