kokodyn
kokodyn

Reputation: 329

How to rewrite it to functional style?

I would like to move some method into java8 functional style.

public static String foo(List<String> arguments, List<String> conditions) {
    for (String s : conditions) {
        for (String argument : arguments) {
            if (argument.contains(s)) {
                return argument;
            }
        }
    }
    return "";
}

My current idea is:

public static String fooFunctional(List<String> arguments, List<String> conditions) {
    return conditions.stream()
            .flatMap(condition -> arguments.stream()
                    .filter(argument -> argument.contains(condition))
                    .findFirst()
                    .map(Stream::of)
                    .orElseGet(Stream::empty))
            .findFirst()
            .orElse("");
}

Is there any shorter version then proposed above?

Upvotes: 1

Views: 187

Answers (2)

Oboe
Oboe

Reputation: 2713

UPDATE

As noticed by @Holger in the comments, a simpler and Java 8 compatible approach:

conditions.stream()
        .flatMap(condition -> arguments.stream()
                .filter(argument -> argument.contains(condition)))
        .findFirst().orElse("");

Java 8:

conditions.stream()
        .map(condition -> arguments.stream()
                .filter(argument -> argument.contains(condition))
                .findFirst())
        .filter(Optional::isPresent)
        .findFirst().map(Optional::get).orElse("");

Java 9+:

You can use Optional.stream():

conditions.stream()
        .flatMap(condition -> arguments.stream()
                .filter(argument -> argument.contains(condition))
                .findFirst().stream())
        .findFirst().orElse("");

Upvotes: 1

marstran
marstran

Reputation: 28036

If it's not important which exact argument you return as long as at least one condition is contained in it, then you can get it a bit shorter by streaming over arguments before conditions. Like this:

return arguments.stream()
    .filter(argument -> conditions.stream()
        .anyMatch(condition -> argument.contains(condition)))
    .findFirst()
    .orElse("");

Upvotes: 0

Related Questions