This expression x -> x * elem;
is going to be de-sugared to a static method, that looks like this:
private static Integer lambda$curring$0(int x, int y){
return x*y;
}
Because you are capturing
the elem
variable inside the lambda, the lambda is said to be a stateful lambda
.
On the other hand, your map
operation needs an actual instance of java.util.Function
- and that is generated at runtime that will kind of look like this:
final class Test2$$Lambda$1 implements java.util.function.Function {
private final Integer arg$1;
private Test2$$Lambda$1(Integer arg$1){
this.arg$1 = arg$1;
}
// static factory method
private static java.util.function.Function get$Lambda(Integer i){
return new Test2$$Lambda$1(i); // instance of self
}
public Integer apply(Integer x) {
return YourClass.lambda$curring$0(this.arg$1, x);
}
}
Before Function.apply
(inside your map operation) is called a new instance of Test2$$Lambda$1
is generated via the static factory method get$Lambda
. This is needed "carry" the elem
variable.
Because of that every time map gets called a new instance is created.
Since your Stream has five initial elements, there will be 10 instances created - for the two map
operations.
But generally this is an implementation detail that might easily change one day - so don't rely on it. Also the creation and collection (by garbage collector) of this short lived instances are quite cheap and it will not impact your app almost at all.