Считать свойства объектов в списке с помощью java 8
Итак, пусть у меня есть Arraylist
объекта Animal
. Этот класс объекта выглядит следующим образом:
class Animal{
String Name;//for example "Dog"
String Color
}
Что я хочу сделать, подсчитывает, сколько разных цветов существует для каждого животного в Arraylist
и помещает их в Map<String,Integer>
, где String
- это имя и Integer
- для количества разных цветов,
Например, если есть 4 черные собаки и 1 белый, эквивалент, помещенный на карту, будет
map.put("Dog",2);
Я знаю, что это можно сделать с помощью Stream
, но я не могу узнать, как это сделать.
Ответы
Ответ 1
Что вы хотите сделать, это операция группировки , используя свойство name в качестве ключа. Это легкая часть. Trickier должен выражать "подсчет различных цветов" как нисходящий коллекционер. Поскольку в JRE нет такого сборщика, мы должны построить его, используя хранилище Set
. Обратите внимание, что даже если он был встроенным, он должен был использовать аналогичное хранилище под капотом. Поэтому сопоставить элементы с цветами, собрать их в Set
s (что подразумевает сохранение только отдельных значений ) и закончить, запросив размер:
Map<String, Integer> map = animalStream.collect(
Collectors.groupingBy(Animal::getName,
Collectors.collectingAndThen(
Collectors.mapping(Animal::getColor, Collectors.toSet()),
Set::size)));
Ответ 2
Это должно работать:
Map<String, Integer> map = animal.stream().collect(
Collectors.groupingBy(
Animal::getName,
Collectors.collectingAndThen(
Collectors.mapping(Animal::getColor, Collectors.toSet()),
Set::size)
)
);
Вот некоторый тестовый код:
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());
}
}
дает
Cat : 2
Dog : 2
Примечание: этот ответ был вдохновлен этим сообщением SO: fooobar.com/info/385802/...