Java 中 Collectors
导入与使用全解析
简介
在 Java 编程中,Collectors
是 java.util.stream
包下的一个实用类,它提供了一系列的静态方法,用于在流操作中进行各种规约操作,比如将流中的元素收集到集合中、进行分组、分区、计算统计信息等。本文将详细介绍 Collectors
的基础概念、使用方法、常见实践以及最佳实践,帮助读者深入理解并高效使用 Collectors
。
目录
- 基础概念
- 使用方法
- 常见实践
- 最佳实践
- 小结
- 参考资料
1. 基础概念
Collectors
类是 Java 8 引入的一个工具类,它实现了各种有用的归约操作,如将元素累积到集合中,根据各种标准对元素进行汇总等。在流处理中,Collectors
通常与 Stream
的 collect()
方法一起使用,将流中的元素进行收集和转换。
collect()
方法是 Stream
接口的一个终端操作,它接受一个 Collector
作为参数,Collector
定义了如何将流中的元素收集到目标容器中。Collectors
类提供了许多预定义的 Collector
实现,方便我们进行常见的收集操作。
2. 使用方法
要使用 Collectors
,首先需要导入 java.util.stream.Collectors
类:
import java.util.stream.Collectors;
以下是一个简单的示例,将一个 List
中的元素收集到另一个 List
中:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class CollectorsExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> collectedNumbers = numbers.stream()
.collect(Collectors.toList());
System.out.println(collectedNumbers);
}
}
在这个示例中,我们使用 Collectors.toList()
方法创建了一个 Collector
,它将流中的元素收集到一个 List
中。然后调用 Stream
的 collect()
方法执行收集操作。
3. 常见实践
3.1 收集到不同的集合
除了 toList()
,Collectors
还提供了 toSet()
和 toMap()
方法,分别用于将流中的元素收集到 Set
和 Map
中。
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class CollectToDifferentCollections {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
// 收集到 Set
Set<Integer> set = numbers.stream()
.collect(Collectors.toSet());
System.out.println("Set: " + set);
// 收集到 Map
Map<Integer, Integer> map = numbers.stream()
.collect(Collectors.toMap(num -> num, num -> num * num));
System.out.println("Map: " + map);
}
}
3.2 分组
Collectors.groupingBy()
方法可以根据指定的分类函数对元素进行分组。
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
}
public class GroupingExample {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 20),
new Person("Bob", 25),
new Person("Charlie", 20)
);
Map<Integer, List<Person>> groupedByAge = people.stream()
.collect(Collectors.groupingBy(Person::getAge));
System.out.println(groupedByAge);
}
}
3.3 分区
Collectors.partitioningBy()
方法可以根据布尔条件对元素进行分区。
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class PartitioningExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Map<Boolean, List<Integer>> partitioned = numbers.stream()
.collect(Collectors.partitioningBy(num -> num % 2 == 0));
System.out.println(partitioned);
}
}
3.4 统计信息
Collectors
还提供了一些方法用于计算统计信息,如 counting()
、summingInt()
、averagingInt()
等。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StatisticsExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
long count = numbers.stream()
.collect(Collectors.counting());
System.out.println("Count: " + count);
int sum = numbers.stream()
.collect(Collectors.summingInt(num -> num));
System.out.println("Sum: " + sum);
double average = numbers.stream()
.collect(Collectors.averagingInt(num -> num));
System.out.println("Average: " + average);
}
}
4. 最佳实践
4.1 使用不可变集合
如果需要一个不可变的集合,可以使用 Collectors.toUnmodifiableList()
、Collectors.toUnmodifiableSet()
和 Collectors.toUnmodifiableMap()
方法。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class ImmutableCollectionExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> immutableList = numbers.stream()
.collect(Collectors.toUnmodifiableList());
// 尝试修改会抛出 UnsupportedOperationException
// immutableList.add(6);
}
}
4.2 组合收集器
可以将多个收集器组合使用,以实现更复杂的收集操作。例如,在分组后对每个组中的元素进行进一步的收集。
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
}
public class CombiningCollectorsExample {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 20),
new Person("Bob", 25),
new Person("Charlie", 20)
);
Map<Integer, Long> countByAge = people.stream()
.collect(Collectors.groupingBy(Person::getAge, Collectors.counting()));
System.out.println(countByAge);
}
}
5. 小结
Collectors
类是 Java 流处理中非常强大的工具,它提供了丰富的静态方法,用于实现各种归约操作。通过使用 Collectors
,我们可以方便地将流中的元素收集到不同的集合中,进行分组、分区和统计等操作。在使用时,建议使用不可变集合和组合收集器,以提高代码的安全性和灵活性。
6. 参考资料
- 《Effective Java》(第 3 版)
- 《Java 8 in Action》