1.简介
在上一篇文章中 ,我写了关于如何使用流和分组对对象集合进行分组的文章。 这很有用,但不涵盖特定的用例。 例如,有时我们不仅需要对事物进行分组,还需要将结果转换为更合适的对象。
在这篇文章中,我们将学习如何将变换和归约应用于groupingBy结果。
- 在这里,您可以查看以下示例的源代码。
2.分组并变换
让我们在上一篇文章中,我们不得不集合所使用的模型我的人谁拥有的宠物 。
现在,我们想知道哪些宠物属于居住在纽约的人。 我们要养宠物,所以我们不能只是分组,因为我们将要归还一群人。 我们需要做的是按城市分组人员,然后将流转换为宠物集合。
为此,我们在组的结果上使用以下映射:
public void groupAndTransform(List<Person> persons) {final Map<String, List<Pet>> petsGroupedByCity = persons.stream().collect(groupingBy(Person::getCity,mapping(Person::getPet, toList())));System.out.println("Pets living in New York: " + petsGroupedByCity.get("NYC"));
}
在分组阶段,我们按城市对人员进行分组,然后执行映射以获取每个人的宠物。
3.分组,转换和归约
前面的示例对于转换对象分组很有用,但是也许我们不想获得每个组的整个列表。 在此示例中,我们仍然希望按所有者所在的城市对宠物进行分组,但是这次我们只想获取每个列表中最老的宠物。
来自Collector的 collectionAndThen方法使我们可以对分组结果进行最终转换:
public void groupTransformAndReduce(List<Person> persons) {final Map<String, Pet> olderPetOfEachCity = persons.stream().collect(groupingBy(Person::getCity,collectOlderPet()));System.out.println("The older pet living in New York is: " + olderPetOfEachCity.get("NYC"));
}private Collector<Person, ?, Pet> collectOlderPet() {return collectingAndThen(mapping(Person::getPet,Collectors.maxBy((pet1, pet2) -> Integer.compare(pet1.getAge(), pet2.getAge()))), Optional::get);}
在按城市对人员进行分组之后,我们收集并然后将每个城市的列表中的每个人都转换为宠物,然后应用减法来获得列表中年龄最大的宠物。
4。结论
Collectors API不仅允许我们对事物的集合进行分组,而且还可以根据需要进行转换和简化以获得不同的对象。
翻译自: https://www.javacodegeeks.com/2016/03/grouping-transforming-reduction-java-8.html