I want to reverse sort a stream such as below but getting compile time error as "The method sorted() in the type IntStream is not applicable for the arguments ((<no type> o1, <no type> o2) -> {})"
. Can anyone correct this
IntStream.range(1, 100)
.filter(x -> x%2 != 0)
.sorted((o1,o2) -> -o1.compareTo(o2))
.forEach(System.out::println);
Sort the stream in reverse order using Stream. sorted() method by passing Comparator. reverseOrder() to it that imposes the reverse of the natural ordering.
To sort an array in Java in descending order, you have to use the reverseOrder() method from the Collections class. The reverseOrder() method does not parse the array. Instead, it will merely reverse the natural ordering of the array.
To sort in reverse order, use Comparator. reverseOrder() in sorted() method.
To get the list in the reverse order, we need to use Collections. reverseOrder() and Collections. sort() methods together.
since you're working with an IntStream
it only has one overload of the sorted method and it's the natural order (which makes sense).
instead, box the stream from IntStream
to Stream<Integer>
then it should suffice:
IntStream.range(1, 100)
.filter(x -> x % 2 != 0)
.boxed() // <--- boxed to Stream<Integer>
.sorted((o1,o2) -> -o1.compareTo(o2)) // now we can call compareTo on Integer
.forEach(System.out::println);
However, as mentioned by @Holger in the comments:
never use a comparator function like
(o1,o2) -> -o1.compareTo(o2)
. It is perfectly legal for acompareTo
implementation to returnInteger.MIN_VALUE
, in which case negation will fail and produce inconsistent results. A valid reverse comparator would be (o1,o2) -> o2.compareTo(o1)
A better approach would be:
IntStream.range(1, 100)
.filter(x -> x % 2 != 0)
.boxed()
.sorted(Comparator.reverseOrder())
.forEachOrdered(System.out::println);
why?
forEachOrdered
(big shout out to @Holger for always reminding me)or as suggested by @Holger it can all be simplified to as little as this:
IntStream.range(0, 50)
.map(i -> 99-i*2)
.forEachOrdered(System.out::println);
btw, in JDK9 starting from the code in your post, you can first simplify it via iterate
to:
IntStream.iterate(1, i -> i <= 99, i -> i + 2)
.boxed()
.sorted(Comparator.reverseOrder())
.forEachOrdered(System.out::println);
With this approach, we can avoid the filter intermediate operation and increment in 2's.
and finally you could simplify it even further with:
IntStream.iterate(99, i -> i > 0 , i -> i - 2)
.forEachOrdered(System.out::println);
With this approach, we can avoid filter
, boxed
,sorted
et al.
If that is your real code, then it may be more efficient to use IntStream.iterate
and generate numbers from 99
to 0
:
IntStream.iterate(99, i -> i - 1)
.limit(100)
.filter(x -> x % 2 != 0)
.forEachOrdered(System.out::println);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With