Понимание ссылки на метод с вновь созданным экземпляром

Я полностью понимаю эту форму:

Set<T> set = new HashSet<>();
list.stream().allMatch(t -> set.add(t));
// And that
list.stream().allMatch(set::add);

Но этот случайный случай меня действительно смущает:

list.stream().allMatch(new HashSet<>()::add);

Самое интересное, что экземпляр hashset создается только один раз.

Основано в этой теме


person user and    schedule 02.11.2016    source источник
comment
Это, кстати, похоже на вопрос, сколько массивов будет создано при выполнении оператора for(int i: new int[] { 1, 2, 4, 6, 9, 42 }) …   -  person Holger    schedule 03.11.2016
comment
Спасибо, это именно то, что я искал. Но это в спецификации или просто текущие подробности?   -  person user and    schedule 03.11.2016
comment
Он указан в JLS§. 15.13.3. Оценка во время выполнения ссылок на методы. В конце есть поясняющая сводка: «Когда выражение ссылки на метод имеет выражение (а не тип), предшествующее разделителю ::, то это подвыражение вычисляется немедленно. […] Это означает, что выражение, предшествующее разделителю ::, оценивается только тогда, когда программа встречает выражение ссылки на метод, и не оценивается повторно при последующих вызовах функционального типа интерфейса. »   -  person Holger    schedule 03.11.2016


Ответы (1)


Это то же самое, что и первое выражение, за исключением того, что вы не сохраняете ссылку на вновь созданный набор в вашем контексте. Если вам не понадобится значение набора после вызова allMatch, это то же самое. По сути, это выражение ссылки на метод с вновь созданным экземпляром HashSet. Хотя на первый взгляд это может сбивать с толку, HashSet создается только один раз, а затем ссылка на метод привязывается к этому вновь созданному экземпляру и используется как таковая при оценке операции allMatch.

Хотя это может быть рабочее решение, оно может быть опасным, особенно с непоследовательными (параллельными) потоковыми конвейерами, поскольку оно нарушает предикат allMatch требование безгражданства в контракте API.

person Nándor Előd Fekete    schedule 02.11.2016