在Java 8中,Stream API的引入为数据处理带来了极大的便利。其中一个非常实用的功能是Collectors.groupingBy(),它允许我们根据特定的分类函数对数据进行分组,从而实现高效...
在Java 8中,Stream API的引入为数据处理带来了极大的便利。其中一个非常实用的功能是Collectors.groupingBy(),它允许我们根据特定的分类函数对数据进行分组,从而实现高效的数据分类与处理。本文将深入探讨Java 8中的分组技巧,帮助您轻松实现数据的高效分类与处理。
groupingBy()Collectors.groupingBy()是一个收集器,它可以将元素根据给定的分类函数进行分组。它有两个重载版本:
groupingBy(Function super T,? extends K> classifier):根据分类函数classifier对元素进行分组。groupingBy(Function super T,? extends K> classifier, Supplier mapFactory):除了分类函数外,还提供了一个映射工厂mapFactory,用于创建分组结果的存储容器。其中,classifier是一个函数,它接受一个元素并返回一个键,该键用于将元素分组。mapFactory是一个供应商,它用于创建用于存储分组结果的容器。
以下是一个简单的单级分组示例,假设我们有一个Person类,包含name和age两个属性,我们想根据年龄对Person对象进行分组:
import java.util.*;
import java.util.stream.Collectors;
class Person { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; }
}
public class GroupingExample { public static void main(String[] args) { List people = Arrays.asList( new Person("Alice", 25), new Person("Bob", 30), new Person("Charlie", 25), new Person("David", 35) ); Map> groupedByAge = people.stream() .collect(Collectors.groupingBy(Person::getAge)); groupedByAge.forEach((age, persons) -> { System.out.println("Age: " + age); persons.forEach(person -> System.out.println(" - " + person.getName())); }); }
} 在上面的代码中,我们根据Person对象的age属性进行了分组,并打印了每个年龄组的人员名单。
在某些情况下,我们可能需要根据多个属性进行分组。以下是一个多级分组的示例,我们同样使用Person类,这次我们根据性别和年龄进行分组:
import java.util.*;
import java.util.stream.Collectors;
class Person { String name; String gender; int age; public Person(String name, String gender, int age) { this.name = name; this.gender = gender; this.age = age; } public String getName() { return name; } public String getGender() { return gender; } public int getAge() { return age; }
}
public class GroupingExample { public static void main(String[] args) { List people = Arrays.asList( new Person("Alice", "Female", 25), new Person("Bob", "Male", 30), new Person("Charlie", "Female", 25), new Person("David", "Male", 35) ); Map>> groupedByGenderAndAge = people.stream() .collect(Collectors.groupingBy(Person::getGender, Collectors.groupingBy(Person::getAge))); groupedByGenderAndAge.forEach((gender, ageGroup) -> { System.out.println("Gender: " + gender); ageGroup.forEach((age, persons) -> { System.out.println(" - Age: " + age); persons.forEach(person -> System.out.println(" - " + person.getName())); }); }); }
} 在这个例子中,我们首先根据性别进行分组,然后在每个性别组内部根据年龄进行分组。
groupingBy()进行聚合除了分组外,groupingBy()还可以与聚合函数一起使用,以实现更复杂的操作。以下是一个使用groupingBy()和collectingAndThen()进行聚合的示例:
import java.util.*;
import java.util.stream.Collectors;
class Person { String name; int salary; public Person(String name, int salary) { this.name = name; this.salary = salary; } public String getName() { return name; } public int getSalary() { return salary; }
}
public class GroupingExample { public static void main(String[] args) { List people = Arrays.asList( new Person("Alice", 50000), new Person("Bob", 60000), new Person("Charlie", 50000), new Person("David", 70000) ); Map> groupedBySalaryMax = people.stream() .collect(Collectors.groupingBy(Person::getName, Collectors.collectingAndThen( Collectors.maxBy(Comparator.comparingInt(Person::getSalary)), Optional::get ))); groupedBySalaryMax.forEach((name, maxSalary) -> { System.out.println("Name: " + name + ", Max Salary: " + maxSalary); }); }
} 在这个例子中,我们根据人员姓名进行分组,并为每个组计算最高薪水。
Java 8的Collectors.groupingBy()是一个强大的工具,它可以帮助我们轻松地对数据进行分组和聚合。通过合理使用groupingBy(),我们可以实现高效的数据分类与处理,从而提高应用程序的性能和可读性。