Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Joining Strings via stream

Tags:

java-8

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.

like image 822
user1156544 Avatar asked Jul 18 '26 16:07

user1156544


1 Answers

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.

Difference between lamdba & method refrence

  • 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().

like image 57
cybersoft Avatar answered Jul 23 '26 10:07

cybersoft



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!