Reputation: 2972
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
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
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