JDC
JDC

Reputation: 4385

Java Streams - Sort if Comparator exists

I have a class where optionally a Comparator can be specified.


Since the Comparator is optional, I have to evaluate its presence and execute the same stream code, either with sorted() or without:

if(comparator != null) {
    [...].stream().map()[...].sorted(comparator)[...];
} else {
    [...].stream().map()[...];
}

Question:
Is there a more elegant way to do this without the code duplication?

Note:
A default Comparator is not an option, I just want to keep the original order of the values I am streaming.

Besides, the elements are already mapped at the point of sorting, so I can not somehow reference the root list of the stream, as I do not have the original elements anymore.

Upvotes: 7

Views: 3351

Answers (6)

Marian Klühspies
Marian Klühspies

Reputation: 17627

Java has nothing built-in for this case yet, and passing "null" would lead to an exception.

You can create a util class StreamUtils and use this function

    /**
     * Resets a .stream().sorted() call and can be used for optional sorters
     *
     * Optional
     * .ofNullable(sorter)
     * .orElse(StreamUtils.naturalOrder())
     */
    public static <T> Comparator<T> naturalOrder() {
        return (o1, o2) -> 0;
    }

Upvotes: 0

123-xyz
123-xyz

Reputation: 637

If you don't mind use third party library StreamEx

StreamEx(source).[...].chain(s -> comparator == null ? s : s.sorted(comparator)).[...];

Upvotes: 2

fps
fps

Reputation: 34460

Another way would be to use Optional:

Stream<Whatever> stream = [...].stream().map()[...];

List<WhateverElse> result = Optional.ofNullable(comparator)
    .map(stream::sorted)
    .orElse(stream)
    .[...] // <-- go on with the stream pipeline
    .collect(Collectors.toList());

Upvotes: 4

user4910279
user4910279

Reputation:

You can accomplish this using an auxiliary function.

static <T, R> R applyFunction(T obj, Function<T, R> f) {
    return f.apply(obj);
}

and

applyFunction([...].stream().map()[...],
    stream -> comparator == null ? stream : stream.sorted(comparator))
    [...];

You don't need to know intermediate stream type.

Upvotes: 0

Boris van Katwijk
Boris van Katwijk

Reputation: 3188

You could define a comparator of your type (I used E as a placeholder here) that will not change the order:

 Comparator<E> NO_SORTING = (one, other) -> 0;

If the comparator field is an Optional of Comparator, you can then use

.sorted(comparator.orElse(NO_SORTING))

Upvotes: 3

Eran
Eran

Reputation: 393821

You can do something like this:

Stream<Something> stream = [...].stream().map()[...]; // preliminary processing
if(comparator != null) {
    stream = stream.sorted(comparator); // optional sorting
}
stream... // resumed processing, which ends in some terminal operation (such as collect)

Upvotes: 9

Related Questions