javaio流层次结构
1.简介
使用Java 8流,可以很容易地根据不同的标准对对象集合进行分组。 在这篇文章中,我们将看到如何从简单的单级分组到更复杂的,涉及多个级分组的分组。
我们将使用两个类来表示我们要分组的对象:人和宠物。
人类
public class Person {private final String name;private final String country;private final String city;private final Pet pet;public Person(String name, String country, String city, Pet pet) {this.name = name;this.country = country;this.city = city;this.pet = pet;}public String getName() {return name;}public String getCountry() {return country;}public String getCity() {return city;}public Pet getPet() {return pet;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", country='" + country + '\'' +", city='" + city + '\'' +'}';}
}
宠物课
public class Pet {private final String name;private final int age;public Pet(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}@Overridepublic String toString() {return "Pet{" +"name='" + name + '\'' +", age=" + age +'}';}
}
在主要方法中,我们创建将在以下各节中使用的集合。
public static void main(String[] args) {Person person1 = new Person("John", "USA", "NYC", new Pet("Max", 5));Person person2 = new Person("Steve", "UK", "London", new Pet("Lucy", 8));Person person3 = new Person("Anna", "USA", "NYC", new Pet("Buddy", 12));Person person4 = new Person("Mike", "USA", "Chicago", new Pet("Duke", 10));List<Person> persons = Arrays.asList(person1, person2, person3, person4);
- 您可以在此处查看源代码。
2.单层分组
分组的最简单形式是单级分组。 在此示例中,我们将按其国家/地区对集合中的所有人员进行分组:
public void singleLevelGrouping(List<Person> persons) {final Map<String, List<Person>> personsByCountry = persons.stream().collect(groupingBy(Person::getCountry));System.out.println("Persons in USA: " + personsByCountry.get("USA"));
}
如果我们看一下地图,就可以看到每个国家如何包含其公民列表:
结果显示居住在指定国家/地区的人:
Persons in USA: [Person{name='John', country='USA', city='New York'}, Person{name='Anna', country='USA', city='New York'}, Person{name='Mike', country='USA', city='Chicago'}]
3.两级分组
在此示例中,我们将不仅按国家/地区分组,还按城市分组。 为此,我们需要实现两级分组。 我们将按国家对人员进行分组,对于每个国家,我们将按其居住城市对人员进行分组。
为了允许进行多级分组,类Collectors中的groupingBy方法支持附加的Collector作为第二个参数:
public static <T, K, A, D>Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,Collector<? super T, A, D> downstream)
让我们使用此方法来实现我们的两级分组:
public void twoLevelGrouping(List<Person> persons) {final Map<String, Map<String, List<Person>>> personsByCountryAndCity = persons.stream().collect(groupingBy(Person::getCountry,groupingBy(Person::getCity)));System.out.println("Persons living in London: " + personsByCountryAndCity.get("UK").get("London").size());
}
如果我们调试执行,我们将看到人员的分布情况:
4.三级分组
在最后一个示例中,我们将更进一步,并按国家,城市和宠物名称对人进行分组。 我将其分为两种方法以提高可读性:
public void threeLevelGrouping(List<Person> persons) {final Map<String, Map<String, Map<String, List<Person>>>> personsByCountryCityAndPetName = persons.stream().collect(groupingBy(Person::getCountry,groupByCityAndPetName()));System.out.println("Persons whose pet is named 'Max' and live in NY: " +personsByCountryCityAndPetName.get("USA").get("NYC").get("Max").size());
}private Collector<Person, ?, Map<String, Map<String, List<Person>>>> groupByCityAndPetName() {return groupingBy(Person::getCity, groupingBy(p -> p.getPet().getName()));
}
现在,我们有了三个嵌套的地图,其中包含每个人员列表:
5.结论
Java 8 Collectors API为我们提供了一种对集合进行分组的简便方法。 通过嵌套收集器,我们可以添加不同的组层以实现多级分组。
翻译自: https://www.javacodegeeks.com/2016/03/multi-level-grouping-streams.html
javaio流层次结构