0

I completely understand this form:

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

But this ad-hoc instance really confuses me:

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

The most interesting is that hashset instantiated only one time.

Founded in this topic

Community
  • 1
  • 1
user and
  • 550
  • 4
  • 9
  • 1
    See [“What is the equivalent lambda expression for System.out::println”](http://stackoverflow.com/a/28025717/2711488) – Holger Nov 03 '16 at 10:39
  • This is, by the way, similar to the question, how many arrays will be created when executing the statement `for(int i: new int[] { 1, 2, 4, 6, 9, 42 }) …` – Holger Nov 03 '16 at 10:44
  • Thanks, that's exactly what I was looking for. But this in spec or just current impl details? – user and Nov 03 '16 at 12:13
  • 2
    It is specified in [JLS§15.13.3. Run-Time Evaluation of Method References](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.13.3). At its end, there is a clarifying summary: “*When a method reference expression has an expression (rather than a type) preceding the :: separator, that subexpression is evaluated immediately. […] This means the expression preceding the :: separator is evaluated only when the program encounters the method reference expression, and is not re-evaluated on subsequent invocations on the functional interface type.*” – Holger Nov 03 '16 at 12:22

1 Answers1

4

It's the same as the first expression except that you don't keep a reference to the newly created set in your context. If you're not going to need the set's value after the allMatch invocation, it's the same. It's essentially a method reference expression with the newly created instance of HashSet. While it might be confusing at first sight, a HashSet is only created once, then the method reference bound to this newly created instance and used as such in the evaluation of the allMatch operation.

While it might be a working solution, it can be dangerous, especially with non-sequential (parallel) stream pipelines because it violates the allMatch predicate's statelessness requirement in the API contract.

Nándor Előd Fekete
  • 6,988
  • 1
  • 22
  • 47