I have code that looks like:
for (SomeObject object : objects) {
if (object.getSomething() == Something.SomethingHighPriority) {
return object;
}
}
for (SomeObject object : objects) {
if (object.getSomething() == Something.SomethingLowPriority) {
return object;
}
}
It is used for getting the first element in collection by some condition. Also, the priority is important. I need firstly look for the one element and just if it doesn't exist look for the second one.
I want to rewrite it using Stream API but I know that streams are used just once. For now I rewrote it in such way but it seems more ugly than before.
Optional<SomeObject> object =
objects.stream()
.filter(object -> object.getSomething() == Something.SomethingHighPriority)
.findFirst();
if (object.isPresent()) {
return object.get();
}
object = objects.stream()
.filter(object -> object.getSomething() == Something.SomethingLowPriority)
.findFirst();
// No other use cases
return object.orElse(null);
Is it possible to make it less boilerplate?
You can chain the two pipelines:
return objects.stream()
.filter(object -> object.getSomething() == Something.SomethingHighPriority)
.findFirst()
.orElseGet(() -> objects.stream()
.filter(object -> object.getSomething() == Something.SomethingLowPriority)
.findFirst()
.orElse(null));
An alternative would be to sort the Stream
by object.getSomething()
in descending order and then return the first element (if it has one of the two required values), but that would take O(NlogN)
which is less efficient.
I think your code is OK, iterating a collection twice is not a bad approach.
But if you want to do it in only one pass, you could collect to a Map
:
Map<Something.Priority, Something> map = objects.stream()
.filter(o -> o.getSomething() == Something.SomethingHighPriority
|| o.getSomething() == Something.SomethingLowPriority)
.collect(Collectors.toMap(
SomeObject::getSomething,
Function.identity(),
(oldObject, newObject) -> oldObject));
SomeObject highPriority = map.get(Something.SomethingHighPriority);
return highPriority == null ? map.get(Something.SomethingLowPriority) : highPriority;
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