Java 8 Stream findFirst () против findAny ()
1. Вступление
API Java 8Stream представил два метода, которые часто неправильно понимают:findAny() иfindFirst().
В этом кратком уроке мы рассмотрим разницу между этими двумя методами и когда их использовать.
Дальнейшее чтение:
Фильтрация потока опций в Java
Краткое и практическое руководство по фильтрации потоков опций в Java 8 и Java 9
Потоки примитивного типа в Java 8
Краткое и практическое руководство по использованию потоков Java 8 с примитивными типами.
Возможность итерации для потоковой передачи в Java
В статье объясняется, как преобразовать Iterable в Stream и почему интерфейс Iterable не поддерживает его напрямую.
2. ИспользуяStream.findAny()
Как следует из названия, методfindAny() позволяет вам найти любой элемент изStream. Используйте его, когда вы ищете элемент, не обращая внимания на порядок встречи:
Метод возвращает экземплярOptional, который пуст, еслиStream пуст:
@Test
public void createStream_whenFindAnyResultIsPresent_thenCorrect() {
List list = Arrays.asList("A","B","C","D");
Optional result = list.stream().findAny();
assertTrue(result.isPresent());
assertThat(result.get(), anyOf(is("A"), is("B"), is("C"), is("D")));
}
При непараллельной работеit will most likely return the first element in the Stream but there is no guarantee for this.
Для максимальной производительности при обработке параллельной операции результат не может быть надежно определен:
@Test
public void createParallelStream_whenFindAnyResultIsPresent_thenCorrect()() {
List list = Arrays.asList(1, 2, 3, 4, 5);
Optional 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.. Очевидно, этот метод используется, когда вам конкретно нужен первый элемент из последовательности.
Когда нет порядка встречи, он возвращает любой элемент изStream. В документации пакетаjava.util.streams говорится:
Потоки могут иметь или не иметь определенныйencounter order. Это зависит от источника и промежуточных операций.
Тип возврата также является экземпляромOptional, который пуст, еслиStream тоже пуст:
@Test
public void createStream_whenFindFirstResultIsPresent_thenCorrect() {
List list = Arrays.asList("A", "B", "C", "D");
Optional result = list.stream().findFirst();
assertTrue(result.isPresent());
assertThat(result.get(), is("A"));
}
Поведение методаfindFirst не меняется в параллельном сценарии. Если порядок встречи существует, он всегда будет вести себя детерминистически.
4. Заключение
В этом руководстве мы рассмотрели методыfindAny() иfindFirst() API Java 8 Streams. МетодfindAny() возвращает любой элемент изStream, а методfindFirst() возвращает первый элемент изStream.
Вы можете найти полный исходный код и все фрагменты кода для этой статьиover on GitHub.