Аргумент метода 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 шт):

Автор решения: had0uken

Ваш второй вариант кода является вариантом "обхода" ограничения, что лямбда выражения имеют доступ ко всем переменным внутри своей области видимости, но не должны их менять. То есть: если вы ВНУТРИ лямбы объявляете переменную - вы ее меняете! (Ведь она начинает указывать на новый объект) Это запрещено! Поэтому первый вариант кода не проходит.

Во втором варианте кода ваша перемення указывает на один и тот же объект (фактически она final) внутреннее состояние объекта может меняться, но переменная все так же указывает на тот же объект на протяжении всего времени выполнения. Поэтому JAVA это допускает

→ Ссылка