Reputation: 19
I need to pick the first result based on 3 checks which need to be executed in sequence. i.e if there is no object that meets criterion 1, then we look for any object meeting criterion 2 and so on. Here is my working code
MyClass result = myObjects.stream()
.filter(s -> s.meetsCriterion1())
.findFirst()
.orElseGet(() -> {
return myObjects.stream()
.filter(s -> s.meetsCriterion2())
.findFirst()
.orElseGet(() -> {
return myObjects.stream()
.filter(s -> s.meetsCriterion3())
.findFirst()
.orElseGet(() -> {
return null;
});
});
});
can we improve this code? I am not sure if there is a way to reuse the first stream to evaluate all the criterion.
Upvotes: 1
Views: 105
Reputation: 28183
I would separate the list of criteria from the logic:
List<Predicate<MyClass>> criteria = Arrays.asList(
MyCass::meetsCriterion1,
MyCass::meetsCriterion2,
MyCass::meetsCriterion3
);
MyClass result = criteria.stream()
.flatMap(c -> myObjects.stream().filter(c).limit(1))
.findFirst()
.orElse(null); // questionable. consider redesigning to avoid null.
Upvotes: 6