Collectors
Java Stream API 的 Collectors
类是一个工厂类,提供了很多静态方法用于创建 Collector
实例,这些实例可以在流操作(如 collect
方法)中作为归约操作(reduction operation)的目标。Collectors
类中的方法允许你以声明方式处理流元素,例如将流元素收集到集合、映射、字符串等中。下面将详细解释几个常用的 Collectors
方法,并给出示例。
1. toList()
将流中的元素收集到一个新的 List
中。
示例:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> collectedNames = names.stream().collect(Collectors.toList());
System.out.println(collectedNames); // 输出: [Alice, Bob, Charlie]
2. toSet()
将流中的元素收集到一个新的 Set
中。由于 Set
不允许重复元素,所以如果流中有重复元素,它们会被忽略。
示例:
List<String> names = Arrays.asList("Alice", "Bob", "Alice");
Set<String> collectedNames = names.stream().collect(Collectors.toSet());
System.out.println(collectedNames); // 输出可能是: [Alice, Bob],具体顺序取决于Set的实现
3. toMap()
将流中的元素收集到一个新的 Map
中。你需要提供键映射函数和值映射函数(可选)。
示例:
List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25)
);
Map<String, Integer> ageMap = people.stream()
.collect(Collectors.toMap(Person::getName, Person::getAge));
System.out.println(ageMap); // 输出: {Alice=30, Bob=25}
// 返回对象
Map<String, Person> personMap = personList.stream()
.collect(Collectors.toMap(Person::getName, Function.identity()));
// 如果有重复对象 返回任意对象
Map<String, Person> personMap = personList.stream()
.collect(Collectors.toMap(Person::getName, Function.identity(), (k1, k2) -> k1));
// 如果有重复对象 指定逻辑对象
Map<String, Person> personMap = personList.stream()
.collect(Collectors.toMap(Person::getName, Function.identity(),
(existingValue, newValue) -> {
// Merge function to handle duplicates
return new Person(existingValue.getName(),
Math.max(existingValue.getAge(), newValue.getAge()));
}));
4. groupingBy()
根据某个属性对流中的元素进行分组,并收集到 Map
中。
示例:
List<Person> people = Arrays.asList(
new Person("Alice", "Female"),
new Person("Bob", "Male"),
new Person("Charlie", "Male")
);
Map<String, List<Person>> genderMap = people.stream()
.collect(Collectors.groupingBy(Person::getGender));
System.out.println(genderMap); // 输出: {Female=[Person{name='Alice', gender='Female'}], Male=[Person{name='Bob', gender='Male'}, Person{name='Charlie', gender='Male'}]}
5. joining()
将流中的字符串元素连接成一个新的字符串。
示例:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
String joinedNames = names.stream()
.collect(Collectors.joining(", "));
System.out.println(joinedNames); // 输出: Alice, Bob, Charlie
6. counting()
对流中的元素进行计数。
示例:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
long count = names.stream()
.collect(Collectors.counting());
System.out.println(count); // 输出: 3
7.averagingDouble/averagingInt/averagingLong:计算流中数值类型元素的平均值。
List<Double> weights = Arrays.asList(60.0, 70.0, 80.0);
double averageWeight = weights.stream()
.collect(Collectors.averagingDouble(d -> d));
System.out.println(averageWeight); // 输出: 70.0
8.summingDouble/summingInt/summingLong:计算流中数值类型元素的总和。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.collect(Collectors.summingInt(n -> n));
System.out.println(sum); // 输出: 15
9.maxBy/minBy:根据提供的比较器找到流中的最大或最小元素
List<String> strings = Arrays.asList("apple", "banana", "cherry");
Optional<String> maxString = strings.stream()
.collect(Collectors.maxBy(Comparator.comparing(String::length)));
maxString.ifPresent(System.out::println); // 输出: banana
10.summarizingDouble/summarizingInt/summarizingLong:提供数值的摘要信息,如总数、平均值、最大值和最小值。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
IntSummaryStatistics stats = numbers.stream()
.collect(Collectors.summarizingInt(n -> n));
System.out.println(stats); // 输出类似: IntSummaryStatistics{count=5, sum=15, min=1, average=3.000000, max=5}