stream-API: замените цикл for-each (с дорогим вызовом операции внутри) потоком - PullRequest
0 голосов
/ 29 августа 2018

Я сейчас пытаюсь улучшить свои навыки в 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;
  }

}

1 Ответ

0 голосов
/ 29 августа 2018

Это должно быть довольно просто:

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