List.stream, Объясните как работает этот код
List<Integer> list = Arrays.asList(8, 2, 7, 11, 2, 5, 7, 11);
int a = list.stream().reduce(Integer.MIN_VALUE, (x, y) -> x > y ? x : y);
int b = list.stream().max((x, y) -> x > y ? x : y).get();
int c = list.parallelStream().reduce(8, (x, y) -> x > y ? x : y);
int d = list.stream().reduce(11, (x, y) -> x < y ? x : y);
int e = list.stream().max(Integer::compare).get();
int f = list.stream().max(Integer::max).get();
Объясните пожалуйста, что делает каждая строчка кода. И почему получается такой ответ (11, 8, 11, 2, 11, 8)
Ответы (1 шт):
a
int a = list.stream().reduce(Integer.MIN_VALUE, (x, y) -> x > y ? x : y);
В этом случае отрабатывает обычный редьюсер. Если кратко, то происходит следующее:
- Аккумулятор инициализируется начальнм значением (Integer.MIN_VALUE в данном случае)
- Для каждого элемента из
listприменяется функция переданная 2-м параметром. В нее передается значение аккумулятора и текущий элемент, после чего в аккумулятор сохраняется результат выполнения функции - В конце
reduceвозвращает значение аккумулятора
В Вашем случае вызовы редьюсера будут примерно такими:
(Integer.MIN_VALUE, 8) -> Integer.MIN_VALUE > 8 ? //возвращается 8
(8, 2) -> 8 > 2 // возвращается 8
(8, 7) -> 8 > 7 // возвращается 8
(8, 11) -> 8 > 11 // возвращается 11
(11, 2) -> 11 > 2 // возвращается 11
(11, 5) -> 11 > 5 // возвращается 11
(11, 7) -> 11 > 7 // возвращается 11
(11, 11) -> 11 > 11 // возвращается 11 и присваивается переменной a
Важно заметить, что разных версях Java порядок вызовов может быть другим, поскольку в документации он не определен
Больше информации по Stream.reduce можно найти в Javadocs, либо поискать что-то в интернете
b
int b = list.stream().max((x, y) -> x > y ? x : y).get();
в метод max передается компаратор, который сравнивает 2 аргумента и возвращает число, которое интерпретируется следующим образом:
- ноль: оба аргумента равны
- положительное число: 1-й аргумент больше, чем 2-й
- отрицательное число: 1-й аргумент меньше, чем 2-й
В джавадоках и различных источниках в интернете можно найти больше информации на эту тему.
В Вашем случае max берет 2 числа из list, и считает, что 1-е из них большее (в данном случае это 8), поскольку компаратор (x, y) -> x > y ? x : y всегда возвращает положительное число для элементов из list. Далее компаратор последовательно вызывается для текущего максимального и всех остальных элементов.
Стоит отметить, что в документации не определено, какой элемент будет браться 1-м и в каком порядке он будет сравниваться с остальными. В данном случае похоже, что первым взялся элемент 8 и делее он передавался 1-м параметром в вызовы компаратора, поэтому в результате map вернул 8. Теоретически в других версиях Java это поведение может поменяться
c
int c = list.parallelStream().reduce(8, (x, y) -> x > y ? x : y);
По сути то же самое, что и для int a = list.stream().reduce(Integer.MIN_VALUE, (x, y) -> x > y ? x : y), только с другим начальным значением аккумулятора и параллельным стримом
d
int d = list.stream().reduce(11, (x, y) -> x < y ? x : y);
То же, что и для int a = list.stream().reduce(Integer.MIN_VALUE, (x, y) -> x > y ? x : y) только с другим начальным значением и поиском минимального вместо максимального значения
e
int e = list.stream().max(Integer::compare).get();
Аналогично int b = list.stream().max((x, y) -> x > y ? x : y).get();, только используется компаратор, который правильно сравнивает целые числа числа
f
int f = list.stream().max(Integer::max).get();
По сути это то же самое, что и int b = list.stream().max((x, y) -> x > y ? x : y).get(); поскольку Integer::max внутри делает практически то же самое, что и (x, y) -> x > y ? x : y