Deb
Deb

Reputation: 2972

Re-write the method with Java 8 lambda

I have written a small method which recive a string and compare the string with an enum property. If it is matched I am returning the specific enum. Here is the working code.

   public static ScreenPlay getAct(String text) {
        ScreenPlay act = null;
        for (ScreenPlay aAct : ScreenPlay.values()) {
            for (String code : aAct.code) {
                if (StringUtils.contains(text, code)) {
                    act = aAct;
                    break;
                }
            }
            if (act != null) {
                break;
            }
        }
        return act;
    }

I am wondering if these could be re-written using the lambda? Any help would be greatly appriciated.

UPDATE:

Below is my try:

Arrays.stream(ScreenPlay.values())
                .forEach(a -> a.code.stream()
.filter(code -> StringUtils.contains(text, code))); // not sure how to get Optional of ScreenPlay

Upvotes: 2

Views: 72

Answers (2)

Ousmane D.
Ousmane D.

Reputation: 56471

You're looking for filter along with findFirst:

Optional<ScreenPlay> act = Arrays.stream(ScreenPlay.values())
                       .filter(aAct -> Arrays.stream(aAct.code)
                             .anyMatch(code -> StringUtils.contains(text, code))                           
                       .findFirst();

Upvotes: 2

JB Nizet
JB Nizet

Reputation: 692101

forEach is a terminal operation, returning nothing. What you want as a result is an Optional: the first ScreenPlay (if it exists) which matches a predicate.

So the code should be

Optional<ScreenPlay> result = stream.filter(screenPlay -> shouldAccept(screenPlay, text))
                                    .findFirst();

Now, you want to implement the shouldAccept(ScreenPlay, String text) method. This method should return true if the screenPlay has at least one code containing the text (or vice-versa, depending on what your StringUtils.contains() method does.

There is a stream method for that: anyMatch():

boolean shouldAccept(ScreenPlay screenPlay, String text) {
    return screenPlay.codes.stream().anyMatch(code -> StringUtils.contains(text, code));
}

Of course, you can inline this method if you want to. Note how good naming (screenPlay instead of aAct, codes instead of code, code instead of act) makes the code much more readable.

Upvotes: 2

Related Questions