I have a stream of unsorted items and a stream of comparators. I want to apply all the comparators onto the stream by using "thenComparing" (Multisort) Is there a more elegant way than the following code to achive this?
Stream unsorted = ...;
Stream<Comparator> comparators = ...;
Comparator compareFunc = comparators.reduce(null, (a, b) -> {
if(a == null) {
return b;
}else {
return a.thenComparing(b);
}
});
Stream result = unsorted.sorted(compareFunc);
Stream sorted (Comparator comparator) returns a stream consisting of the elements of this stream, sorted according to the provided Comparator. For ordered streams, the sort method is stable but for unordered streams, no stability is guaranteed. It is a stateful intermediate operation i.e, it may incorporate state from previously seen elements ...
In java 8, Comparator can be instantiated using lambda expression. We can also reverse the natural ordering as well as ordering provided by Comparator. Stream< T > sorted (Comparator<? super T > comparator) Where, Stream is an interface and T is the type of stream elements. comparator is used to compare stream elements.
Stream< T > sorted (Comparator<? super T > comparator) Where, Stream is an interface and T is the type of stream elements. comparator is used to compare stream elements. Below given are some examples to understand the implementation of the function in a better way.
Sorting a list in Java 8 is very easy with inbuilt support for comparators chaining. You created independent field sorter by implementing Comparator interface, and the chain them in Collection.sort () method.
Don’t use an identity value for Comparator
s. If the comparators
stream is empty (i.e. does not contain any Comparator
) you should not sort:
Stream result=comparators.reduce(Comparator::thenComparing)
.map(unsorted::sorted).orElse(unsorted);
Note that if the comparators
stream contains only a single Comparator
, that Comparator
will be the result of the reduction.
The method reference passed to Optional.map
might need some experience to get used to it. So it might be worth using the more verbose lambda syntax to show what’s going on there:
Stream<String> result=comparators.reduce(Comparator::thenComparing)
.map((comparator) -> unsorted.sorted(comparator)).orElse(unsorted);
That’s a matter of programming style or personal preference and might change over time.
Using Mark Peters' suggestion and mixing it with a method reference, you could write your comparator this way:
Comparator compareFunc = comparators.reduce((a, b) -> 0, Comparator::thenComparing);
Or stealing a bit from Holger instead:
Optional<Comparator> compareFunc = comparators.reduce(Comparator::thenComparing);
Stream<?> result = compareFunc.isPresent() ? result.sorted(compareFunc.get())
: unsorted;
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