Java Stream收集
外观
Java Stream收集[编辑 | 编辑源代码]
Java Stream收集(Collectors)是Java Stream API中的一个核心概念,它允许开发者通过`Collectors`工具类将流中的元素聚合为集合、字符串、统计结果或其他数据结构。收集操作通常通过`Stream.collect()`方法实现,是流处理的终端操作之一。
介绍[编辑 | 编辑源代码]
在Java 8引入的Stream API中,流(Stream)代表一系列元素,支持顺序或并行操作。而收集(Collecting)是流处理的最后一步,将流中的元素转换为具体的数据结构(如`List`、`Set`、`Map`)或计算聚合结果(如求和、平均值)。`Collectors`类提供了丰富的静态工厂方法,用于实现常见的收集操作。
基本收集操作[编辑 | 编辑源代码]
以下是一些基本的收集操作示例:
收集为List[编辑 | 编辑源代码]
将流中的元素收集到`List`中:
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CollectExample {
public static void main(String[] args) {
Stream<String> stream = Stream.of("Java", "Python", "C++");
List<String> list = stream.collect(Collectors.toList());
System.out.println(list); // 输出: [Java, Python, C++]
}
}
收集为Set[编辑 | 编辑源代码]
将流中的元素收集到`Set`中(自动去重):
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CollectExample {
public static void main(String[] args) {
Stream<String> stream = Stream.of("Java", "Python", "Java");
Set<String> set = stream.collect(Collectors.toSet());
System.out.println(set); // 输出: [Java, Python](顺序可能不同)
}
}
收集为Map[编辑 | 编辑源代码]
将流中的元素转换为键值对:
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CollectExample {
public static void main(String[] args) {
Stream<String> stream = Stream.of("Java", "Python", "C++");
Map<String, Integer> map = stream.collect(
Collectors.toMap(s -> s, String::length)
);
System.out.println(map); // 输出: {Java=4, Python=6, C++=3}
}
}
高级收集操作[编辑 | 编辑源代码]
`Collectors`还支持更复杂的聚合操作,如分组、分区和统计。
分组(Grouping By)[编辑 | 编辑源代码]
按某个条件对流中的元素分组:
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class GroupingExample {
public static void main(String[] args) {
Stream<String> stream = Stream.of("Java", "Python", "C++", "JavaScript");
Map<Integer, List<String>> groupedByLength = stream.collect(
Collectors.groupingBy(String::length)
);
System.out.println(groupedByLength);
// 输出: {2=[C++], 4=[Java], 6=[Python], 10=[JavaScript]}
}
}
分区(Partitioning By)[编辑 | 编辑源代码]
将流中的元素分为`true`和`false`两组:
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class PartitioningExample {
public static void main(String[] args) {
Stream<String> stream = Stream.of("Java", "Python", "C++", "JavaScript");
Map<Boolean, List<String>> partitioned = stream.collect(
Collectors.partitioningBy(s -> s.length() > 4)
);
System.out.println(partitioned);
// 输出: {false=[Java, C++], true=[Python, JavaScript]}
}
}
统计(Summarizing)[编辑 | 编辑源代码]
计算数值流的统计信息(总和、平均值、最大值等):
import java.util.IntSummaryStatistics;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StatisticsExample {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
IntSummaryStatistics stats = stream.collect(
Collectors.summarizingInt(Integer::intValue)
);
System.out.println("总和: " + stats.getSum()); // 输出: 15
System.out.println("平均值: " + stats.getAverage()); // 输出: 3.0
System.out.println("最大值: " + stats.getMax()); // 输出: 5
}
}
自定义收集器[编辑 | 编辑源代码]
如果内置的`Collectors`不满足需求,可以通过`Collector.of()`自定义收集器。以下是一个拼接字符串的自定义收集器示例:
import java.util.stream.Collector;
import java.util.stream.Stream;
public class CustomCollectorExample {
public static void main(String[] args) {
Stream<String> stream = Stream.of("Java", "Python", "C++");
String result = stream.collect(
Collector.of(
StringBuilder::new,
StringBuilder::append,
StringBuilder::append,
StringBuilder::toString
)
);
System.out.println(result); // 输出: JavaPythonC++
}
}
实际应用案例[编辑 | 编辑源代码]
假设有一个订单列表,需要按用户分组并计算每个用户的订单总金额:
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class Order {
String user;
double amount;
Order(String user, double amount) {
this.user = user;
this.amount = amount;
}
}
public class OrderAnalysis {
public static void main(String[] args) {
List<Order> orders = List.of(
new Order("Alice", 100.0),
new Order("Bob", 200.0),
new Order("Alice", 150.0)
);
Map<String, Double> totalByUser = orders.stream()
.collect(Collectors.groupingBy(
o -> o.user,
Collectors.summingDouble(o -> o.amount)
));
System.out.println(totalByUser); // 输出: {Alice=250.0, Bob=200.0}
}
}
性能注意事项[编辑 | 编辑源代码]
- 并行流(`parallelStream()`)可以加速收集操作,但需确保收集器是线程安全的。
- 对于大数据集,避免频繁调用`collect()`,尽量合并操作。
总结[编辑 | 编辑源代码]
Java Stream收集是流处理的核心功能之一,通过`Collectors`类可以实现从简单聚合到复杂分组的操作。掌握这些技巧能显著提升代码的简洁性和可读性。
通过本文的学习,你应该能够熟练使用`Collectors`完成各种流收集任务。