It's better to express this behavior in the code:
List<Integer> list= new ArrayList<>();
Stream.of(1,2,3).forEach(i -> list.add(1)); // COMPILES
Stream.of(1,2,3).forEach(i -> true); // DOES NOT COMPILE!
forEach(...)
accepts Consumer
, but why does the first example compile if List interface has following signature boolean add(E e)
? whereas the second yields:
bad return type in lambda expression: boolean cannot be converted to void
Though you might be looking just for
Stream.of(1,2,3).forEach(list::add); // adding all to `list`
why does the first example compile if List interface has following signature boolean add(E e)
Primarily because the return type of the method is ignored in the first call. This is what it expands to:
Stream.of(1,2,3).forEach(new Consumer<Integer>() {
@Override
public void accept(Integer i) {
list.add(1); // ignored return type
}
}); // COMPILES
On the other hand, the other lambda representation is more like a Predicate
(which is also a FunctionalInterface
) represented as returning true
always from its test
method. If you even try to represent it as a Consumer
, it might just look like
Stream.of(1,2,3).forEach(new Consumer<Integer>() {
@Override
public void accept(Integer i) {
return true; // you can correlate easily now why this wouldn't compile
}
}); // DOES NOT COMPILE!
To add to the design basis via a comment from Brian
Java allows you to call a method and ignore the return value (a method invocation expression as a statement). Since we allow this at the invocation, we also allow this when adapting a method to a functional interface whose arguments are compatible but the functional interface is void-returning.
Edit: To put it in his own words as close to the language spec:
More precisely,
list.add(x)
is a statement expression, and therefore is void-compatible.true
is not a statement expression, and therefore not void-compatible.forEach(Consumer)
requires a void-compatible lambda.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With