I am trying to join a list of names:
List<String> names;
names = books.stream()
.map( b -> b.getName() )
.filter( n -> ( (n != null) && (!n.isEmpty()) ) )
.collect(Collectors.joining(", "));
This does not compile saying:
incompatible types. inference variable R has incompatible bounds
So after some research, it seems that there is something I misunderstood. I thought that .map( b -> b.getName() ) returned/changed the type to a String, and it seems something is wrong there. If I use .map(Book::getName) instead, I still get an error, but I probably don't fully understand the difference.
However, this does not complain:
List<String> names;
names = books.stream()
.map( b -> b.getName() )
.map( Book::getName )
.filter( n -> ( (n != null) && (!n.isEmpty()) ) )
.collect(Collectors.joining(", "));
Can someone explain me why? Some didactic explanation about differences between .map( b -> b.getName() ) and .map(Book::getName) are appreciated too, since I think I didn't get it right.
The joining(", ") collector will collect and join all Strings into a single string using the given separator. The returning type of collect in this case is String, but you are trying to assign the result to a List. If you want to collect Strings into a List, use Collectors.toList().
If you have a collection with Book instances, then it will be enough to map a stream of Books to a stream of Strings once.
A lamdba expression may be written as a block, containing multiple operations:
b -> {
// here you can have other operations
return b.getName();
}
if lambda has single operation, it can be shortened:
b -> b.getName()
Method reference is just a "shortcut" for a lambda with a single operation. This way:
b -> b.getName()
can be replaced with:
Book::getName
but if you have a lambda like this:
b -> b.getName().toLowerCase()
you cant use a reference to the getName method, because you are making and additional call to toLowerCase().
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