Java 8 here. I have an array of Strings:
String[] animals = getsomehow(); // "dogs", "cats", "sheep", etc.
Then I have a map where the keys are Strings (specifically, the same literal values as some of the animals in the array above), and the values are a count (representing the number of those animals):
Map<String,Integer> animalCounts = new HashMap<String,Integer>(); animalCounts.put("sheep", 4); animalCounts.put("dogs", 2); animalCounts.put("cats", 0); animalCounts.put("porcupines", null); animalCounts.put("dolphins", 43);
I am trying to figure out how to use the Stream API to iterate over my animals
array, and come up with a total number of animals. For instance, if my animals
array had “sheep” and “dolphins” in it, then the total number of animals would be 4 + 43 = 47.
My best attempt so far:
int totalAnimals = Arrays.stream(animals) .reduce( 0, (subtotal, animal) -> subtotal + animalCounts.get(animal));
However this yields a compiler error for the identity value of 0
:
“Required type: String“
Can anyone spot where I’m going awry?
Advertisement
Answer
Can anyone spot where I’m going awry?
You’re using the 2-argument version of reduce
:
T reduce(T identity, BinaryOperator<T> accumulator)
As you can see, the identity value and the output has to be of the same type as the input, so it must be String
.
Solution would be to use the 3-argument version of reduce
:
<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
As an alternative, you can do it like this:
int totalAnimals = Arrays.stream(animals) .map(animalCounts::get) .filter(Objects::nonNull) .mapToInt(Integer::intValue) .sum();