Varun Upadhyay
Varun Upadhyay

Reputation: 39

How to apply Consumer with a map in Java?

I have created a Consumer which takes a string and makes it uppercase. I am trying to implement it along with a map to make all the strings in a list to uppercase. I understand that this can be done easily using String::toUpperCase but I am trying to do it with a Consumer and I am getting the following error

java: incompatible types: inferred type does not conform to upper bound(s)
    inferred: void
    upper bound(s): java.lang.Object

Here is my code

Consumer<String> upper = name -> name.toUpperCase();
names.stream().map(name -> upper.accept(name)).collect(Collectors.joining(" "))

I want to know if this is the correct way to use Consumer interface and also what would be a typical scenario where using Consumer would be helpful?

Upvotes: 3

Views: 7473

Answers (3)

Sagar Zond
Sagar Zond

Reputation: 39

Consumer will never work for Stream map operation. Stream map operation taking a Function as an argument. You can do this with following code also :

Function<String, String> upper = name -> name.toUpperCase();
names.stream().map(upper).collect(Collectors.joining(" "))

Upvotes: 1

Lino
Lino

Reputation: 19926

Using a Consumer will never work, as you might expect it, because String.toUpperCase() returns a new instance of a String. Look at following example:

Consumer<String> toUpper = s -> {
    s.toUpperCase();
};

You see that nothing gets returned. And so the upper case string will be lost / discarded.

To do what you desire you have to use a Function which accepts a String and returns a String e.g:

Function<String, String> toUpper = String::toUpperCase;

With that you then can use the following statement:

Map<Key, String> map = ...;
map.entrySet().forEach(e -> {
    e.setValue(e.getKey(), toUpper.apply(e.getValue()));
}

To get what you intended in the first place.

Upvotes: 0

Jacob G.
Jacob G.

Reputation: 29690

Consumer#accept returns nothing (void), so it will not compile, as Stream#map accepts a Function<? super T, ? extends R>. Instead of a Consumer, you can use a UnaryOperator<String> (which is a special Function<T, T>):

UnaryOperator<String> upper = String::toUpperCase;

names.stream()
     .map(upper)
     .collect(Collectors.joining(" "));

You also don't even need to store it in a local variable, as it can be inlined:

names.stream()
     .map(String::toUpperCase)
     .collect(Collectors.joining(" "));

Upvotes: 1

Related Questions