stream-API:用流替换for-each循环(内部进行昂贵的操作调用)

时间:2018-08-29 13:26:30

标签: java-8 java-stream

我目前正在尝试提高Java8技能,但偶然发现了这种情况。 我的目标是用方法foo中的Java8流替换方法fooStream中的现有循环。

问题是,我在循环内调用了一个极其昂贵的操作,想在此调用的结果符合我的期望时退出该操作。现在,我的流实现总是比我以前的循环实现多进入一次非常昂贵的操作(在map调用中)。

可以改进我的流实现以阻止此额外调用吗?

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;
  }

}

1 个答案:

答案 0 :(得分:5)

这应该很简单:

return someList //
            .stream() //
            .map(p -> extremelyExpensiveOperation(p, "streamFilter"))
            .filter(Objects::nonNull)
            .findFirst()
            .orElse(null);