Reputation: 16525
Is there some nice way to rewrite the following loop, in which I am saving temporary results, using Java 8 Stream
?
Integer resultByCon1 = null, resultByCon2 = null;
for (Foo foo : bar) {
if (conditional1 && conditional2) {
return foo.getResult();
}
if (conditional1) {
resultBycon1 = foo.getResult();
}
if (conditional2) {
resultBycon2 = foo.getResult();
}
}
return resultByCon1 != null ? resultByCon1
: (resultByCon2 != null ? resultByCon2 : bar.get(0).getResult());
Upvotes: 2
Views: 149
Reputation: 50716
Here's a solution that could be considered more elegant, but it requires a full pass for each condition. That is, it will return as soon as it finds an element matched by a condition, but it only evaluates one condition per pass (to preserve condition precedence). If you're dealing with a small list, you may be willing to take the hit:
List<Predicate<Foo>> conditions = Arrays.asList(
foo -> conditional1 && conditional2,
foo -> conditional1,
foo -> conditional2,
foo -> true
);
return conditions.stream()
.map(condition -> bar.stream().filter(condition))
.map(Stream::findFirst)
.filter(Optional::isPresent)
.findFirst()
.map(Optional::get)
.map(Foo::getResult)
.get();
Upvotes: 1
Reputation: 393811
Here's one way, though I'm not sure how "nice" it is:
Integer[] resultByCon = new Integer[2];
return bar.stream()
.filter (f -> {
if (conditional1 && conditional2) {
return true;
}
if (conditional1) {
resultBycon[0] = foo.getResult();
}
if (conditional2) {
resultBycon[1] = foo.getResult();
}
return false;
})
.map(Foo::getResult)
.findFirst()
.orElseGet (() -> resultByCon[0] != null ?
resultByCon[0] :
(resultByCon[1] != null ? resultByCon[1] : bar.get(0).getResult()));
It contains all the logic in a single Stream
pipeline, but it's probably less readable than your original code.
You may be able to do better using reduce()
.
Upvotes: 1