Перейти к основному содержимому

Java 8 Stream findFirst() против findAny()

· 2 мин. чтения

Задача: Сумма двух чисел

Напишите функцию twoSum. Которая получает массив целых чисел nums и целую сумму target, а возвращает индексы двух чисел, сумма которых равна target. Любой набор входных данных имеет ровно одно решение, и вы не можете использовать один и тот же элемент дважды. Ответ можно возвращать в любом порядке...

ANDROMEDA

1. Обзор

Java 8 Stream API представил два метода, которые часто понимают неправильно: findAny() и findFirst() .

В этом кратком руководстве мы рассмотрим разницу между этими двумя методами и когда их использовать.

2. Использование Stream.findAny()

Как следует из названия, метод findAny() позволяет нам найти любой элемент из Stream . Мы используем его, когда ищем элемент, не обращая внимания на порядок обнаружения:

Метод возвращает необязательный экземпляр, который пуст, если Stream пуст:

@Test
public void createStream_whenFindAnyResultIsPresent_thenCorrect() {
List<String> list = Arrays.asList("A","B","C","D");

Optional<String> result = list.stream().findAny();

assertTrue(result.isPresent());
assertThat(result.get(), anyOf(is("A"), is("B"), is("C"), is("D")));
}

При непараллельной операции он, скорее всего, вернет первый элемент в Stream , но на это нет никаких гарантий.

Для максимальной производительности при обработке параллельной операции невозможно достоверно определить результат:

@Test
public void createParallelStream_whenFindAnyResultIsPresent_thenCorrect()() {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> result = list
.stream().parallel()
.filter(num -> num < 4).findAny();

assertTrue(result.isPresent());
assertThat(result.get(), anyOf(is(1), is(2), is(3)));
}

3. Использование Stream.findFirst()

Метод findFirst() находит первый элемент в потоке . Итак, мы используем этот метод, когда нам нужен первый элемент последовательности.

Когда нет порядка встречи, он возвращает любой элемент из Stream . Согласно документации пакета java.util.streams , «потоки могут иметь или не иметь определенный порядок встречи. Это зависит от источника и промежуточных операций».

Тип возвращаемого значения также является необязательным экземпляром, который пуст, если Stream тоже пуст:

@Test
public void createStream_whenFindFirstResultIsPresent_thenCorrect() {

List<String> list = Arrays.asList("A", "B", "C", "D");

Optional<String> result = list.stream().findFirst();

assertTrue(result.isPresent());
assertThat(result.get(), is("A"));
}

Поведение метода findFirst не меняется в параллельном сценарии. Если порядок встречи существует, он всегда будет вести себя детерминировано.

4. Вывод

В этой статье мы рассмотрели методы findAny() и findFirst() API Java 8 Streams.

Метод findAny() возвращает любой элемент из Stream , а метод findFirst() возвращает первый элемент в Stream .

Полный исходный код и все фрагменты кода для этой статьи закончились на GitHub .