首页 > 解决方案 > stream-API:用流替换 for-each 循环(内部有昂贵的操作调用)

问题描述

我目前正在尝试提高我的 Java8 技能并偶然发现了这个案例。foo我的目标是用方法中的一些 Java8 流替换现有的方法中的循环fooStream

问题是,我在循环内调用了一个极其昂贵的操作,并且希望在此调用的结果符合我的期望时退出它。我的流实现现在总是比我的老式循环实现多一次(在地图调用中)进入极其昂贵的操作。

可以改进我的流实现以防止这种额外的调用吗?

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

}

标签: java-8java-stream

解决方案


这应该相当简单:

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

推荐阅读