流的多层次分组
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
總結
- 上一篇: linux编译命令(linux下编译)
- 下一篇: 使用Spring-Retry重试处理