Аргумент метода collect
Меня интересует данный вариант метода collect:
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);
Почему я не могу задать 1-й аргумент следующим образом? Пример:
public static void main(String[] args) {
List<Integer> list1 = of(1, 2, 3, 4);
List<Integer> even = list1.stream()
.filter(a->a%2==0)
.collect(Supplier<ArrayList> sp = ()->new ArrayList<>(), (a, b)->a.add(b), (a, b)->a.addAll(b));
System.out.println(even);
}
Но при этом работает следующая реализация:
public static void main(String[] args) {
Supplier<ArrayList> sp = ()->new ArrayList<>();
List<Integer> list1 = of(1, 2, 3, 4);
List<Integer> even = list1.stream()
.filter(a->a%2==0)
.collect(sp, (a, b)->a.add(b), (a, b)->a.addAll(b));
System.out.println(even);
}
P.S Я знаю, что можно всё и короче задать, но меня интересует, почему именно не работает?
Ответы (1 шт):
Ваш второй вариант кода является вариантом "обхода" ограничения, что лямбда выражения имеют доступ ко всем переменным внутри своей области видимости, но не должны их менять. То есть: если вы ВНУТРИ лямбы объявляете переменную - вы ее меняете! (Ведь она начинает указывать на новый объект) Это запрещено! Поэтому первый вариант кода не проходит.
Во втором варианте кода ваша перемення указывает на один и тот же объект (фактически она final) внутреннее состояние объекта может меняться, но переменная все так же указывает на тот же объект на протяжении всего времени выполнения. Поэтому JAVA это допускает