Reputation: 39
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
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
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
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