So let's suppose I have an Arraylist
of the object Animal
. That class of the object is like this:
class Animal{
String Name;//for example "Dog"
String Color
}
What I want to do, is count how many different colors exist for each animal in the ArrayList
and put them in a Map<String,Integer>
where String
is the Name and Integer
is for the number of different colors.
For example if there are 4 black dogs and 1 white the equivalent put to the map would be
map.put("Dog",2);
I know it can be done using Stream
but I can't find out how.
The size of an ArrayList can be obtained by using the java. util. ArrayList. size() method as it returns the number of elements in the ArrayList i.e. the size.
Stream count() method in Java with examples long count() returns the count of elements in the stream. This is a special case of a reduction (A reduction operation takes a sequence of input elements and combines them into a single summary result by repeated application of a combining operation).
This should work:
Map<String, Integer> map = animal.stream().collect(
Collectors.groupingBy(
Animal::getName,
Collectors.collectingAndThen(
Collectors.mapping(Animal::getColor, Collectors.toSet()),
Set::size)
)
);
Here some test-code:
public static void main(String[] args) {
List<Animal> animal = new ArrayList<>();
animal.add(new Animal("Dog","black"));
animal.add(new Animal("Dog","black"));
animal.add(new Animal("Dog","blue"));
animal.add(new Animal("Cat","blue"));
animal.add(new Animal("Cat","white"));
Map<String, Integer> map = animal.stream().collect(
Collectors.groupingBy(
Animal::getName,
Collectors.collectingAndThen(
Collectors.mapping(Animal::getColor, Collectors.toSet()),
Set::size)
)
);
for(Entry<String, Integer> entry:map.entrySet()) {
System.out.println(entry.getKey()+ " : "+entry.getValue());
}
}
gives
Cat : 2
Dog : 2
Note: this answer was inspired by this SO post: https://stackoverflow.com/a/30282943/1138523
What you want to do is a grouping operation using the name property as key. That’s the easy part. Trickier is to express “count of distinct colors” as downstream collector. Since there is no such collector in the JRE, we have to built one, utilizing a Set
storage. Note that even if there was a built-in one, it had to use a similar storage under the hood. So we map the elements to colors, collect them into Set
s (which implies keeping distinct values only) and finish by querying the size:
Map<String, Integer> map = animalStream.collect(
Collectors.groupingBy(Animal::getName,
Collectors.collectingAndThen(
Collectors.mapping(Animal::getColor, Collectors.toSet()),
Set::size)));
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