Reputation: 3461
I'm currently trying to improve my Java8 skills and stumbled upon this case.
My aim is to replace the existing loop in method foo
with some Java8 stream in method fooStream
.
The problem is, that I'm calling an extremely expensive operation inside the loop and want to exit it when the result of this call meets my expectations. My stream-implementation now always enters the extremely expensive operation one time more (in the map-call) than my old fashioned loop-implementation.
Can my stream-implementation be improved to prevent this extra call?
public class Foo {
public static void main(final String[] args) {
final List<String> someList = Arrays.asList(null, null, "xxx", null, null, "foo");
foo(someList);
fooStream(someList);
}
public static String foo(final List<String> someList) {
for (final String foo : someList) {
final String result = extremelyExpensiveOperation(foo, "loop");
if (result != null) {
return result;
}
}
return null;
}
public static String fooStream(final List<String> someList) {
return someList //
.stream() //
.filter(p -> extremelyExpensiveOperation(p, "streamFilter") != null) //
.map(p -> extremelyExpensiveOperation(p, "streamMap")) //
.findFirst().orElse(null);
}
private static String extremelyExpensiveOperation(final String foo, final String operation) {
System.out.println("entered extremelyExpensiveOperation: " + operation);
// do some extremely expensive operation
// but in our show and tell case just return foo
return foo;
}
}
Upvotes: 4
Views: 121
Reputation: 120848
This should be fairly simple:
return someList //
.stream() //
.map(p -> extremelyExpensiveOperation(p, "streamFilter"))
.filter(Objects::nonNull)
.findFirst()
.orElse(null);
Upvotes: 5