PraveenS
PraveenS

Reputation: 19

can we improve this code?

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

Answers (1)

Misha
Misha

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

Related Questions