Consider the following snippet:
Stream.of(stringList, Arrays.asList(1))
.map(list -> list)
.reduce((list1, list2) -> {list1.addAll(list2); return list1;});
As far as I can tell, this should not compile because the Stream<? extends List<? extends Whatever>>
type being inferred after map()
takes the Capture Conversion to a restricted type that is applicable for only 1 execution and when it reaches the reduce()
function - it should change to different restricted types that are unrelated.
Calling list1.addAll(list2)
should thus not compile.
I'm not sure how the Type Inference rules internally work for this. I would like to understand the detailed steps regarding the inference procedure for this particular case.
Note that it does not compile without the map(list -> list)
.
Edit: based on comments of @Didier L, I would like to clarify what I mean by applicable for only 1 execution
in the above question based on my understanding-:
- the capture conversion converts the wildcard to a non-representable type only for one single expression evaluation
- even if the variable is same - but used somewhere else in the program - the type being assumed for the next time will be different from what it was assumed before.
- if this is loop - then the capture conversion runs only for the scope of the loop - and should not escape out of the loop. Consider this code:
List<String> stringLists = new ArrayList<>();
List<?> list = stringLists;
list.add(list.get(9)); // this will fail
- here
list.get(9)
will be capture converted to the typeX
- but the
list.add(...)
may have the typeY
- as assumed by another capture conversion of<?>
by the compiler - so the addition of
X
to typeY
is not allowed because of above restriction.
>` that does the same as the lambda, that class should compile, right? And then, what should prevent using it as `reduce(new ListBinaryOperator<>())` operation? However, why does the compiler still reject it without the `map()`?