关于 Java Stream 流的常见操作及示例,涵盖数据过滤、转换、聚合等高频使用场景
一、基础操作
- 过滤数据 (filter)
Listnumbers = Arrays.asList(1, 2, 3, 4, 5, 6);
ListevenNumbers = numbers.stream()
.filter(n -> n % 2 == 0) // 过滤偶数
.collect(Collectors.toList()); // [2, 4, 6] - 数据转换 (map)
Listnames = Arrays.asList("Alice", "Bob", "Charlie");
ListnameLengths = names.stream()
.map(String::length) // 转换为名字长度
.collect(Collectors.toList()); // [5, 3, 7] - 扁平化嵌套集合 (flatMap)
List<List> nestedList = Arrays.asList(
Arrays.asList(1, 2),
Arrays.asList(3, 4, 5)
);
ListflatList = nestedList.stream()
.flatMap(Collection::stream) // 扁平化为单一流
.collect(Collectors.toList()); // [1, 2, 3, 4, 5]
二、聚合操作
- 去重 (distinct)
Listnums = Arrays.asList(1, 2, 2, 3, 3, 3);
ListuniqueNums = nums.stream()
.distinct() // 去重
.collect(Collectors.toList()); // [1, 2, 3] - 排序 (sorted)
Listwords = Arrays.asList("banana", "apple", "cherry");
ListsortedWords = words.stream()
.sorted() // 自然排序
.collect(Collectors.toList()); // [apple, banana, cherry]
// 自定义排序规则
List
.sorted((a, b) -> b.length() - a.length()) // 按长度倒序
.collect(Collectors.toList()); // [banana, cherry, apple]
3. 限制与跳过 (limit/skip)
List
.skip(3) // 跳过前3个 → 4,5,6,7,8,9
.limit(4) // 取前4个 → 4,5,6,7
.boxed()
.collect(Collectors.toList());
三、终端操作
- 统计聚合
Listnumbers = Arrays.asList(1, 2, 3, 4, 5);
// 求和
int sum = numbers.stream().mapToInt(Integer::intValue).sum(); // 15
// 平均值
OptionalDouble avg = numbers.stream().mapToInt(Integer::intValue).average();
// 最大值/最小值
Optional
2. 匹配检查
List
boolean allEven = nums.stream().allMatch(n -> n % 2 == 0); // true
boolean anyGreaterThan5 = nums.stream().anyMatch(n -> n > 5); // true
boolean noneNegative = nums.stream().noneMatch(n -> n < 0); // true
- 遍历元素 (forEach)
Listlist = Arrays.asList("a", "b", "c");
list.stream().forEach(System.out::println); // 输出 a b c
四、高级操作
-
分组 (groupingBy)
Listwords = Arrays.asList("apple", "banana", "cherry", "date");
Map<Integer, List> groupByLength = words.stream()
.collect(Collectors.groupingBy(String::length));
// 结果: -
分区 (partitioningBy)
Listnumbers = Arrays.asList(1, 2, 3, 4, 5, 6);
Map<Boolean, List> partitioned = numbers.stream()
.collect(Collectors.partitioningBy(n -> n % 2 == 0));
// 结果: -
连接字符串 (joining)
Listlanguages = Arrays.asList("Java", "Python", "C++");
String joined = languages.stream()
.collect(Collectors.joining(", ", "[", "]")); // [Java, Python, C++] -
归约操作 (reduce)
Listnums = Arrays.asList(1, 2, 3, 4);
Optionalproduct = nums.stream()
.reduce((a, b) -> a * b); // 123*4=24
五、并行流
List
// 并行计算总和
int sum = numbers.parallelStream()
.mapToInt(Integer::intValue)
.sum();
// 注意线程安全问题
List
numbers.parallelStream().forEach(safeList::add);
六、实用技巧
- 集合转 Map
Listpeople = Arrays.asList(
new Person("Alice", 25),
new Person("Bob", 30)
);
Map<String, Integer> nameToAge = people.stream()
.collect(Collectors.toMap(Person::getName, Person::getAge));
-
跳过空值
Listlist = Arrays.asList("a", null, "c", null);
ListnonNullList = list.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList()); // [a, c] -
处理文件流
try (Streamlines = Files.lines(Paths.get("data.txt"))) {
ListfilteredLines = lines
.filter(line -> line.contains("error"))
.collect(Collectors.toList());
} // 自动关闭流
注意事项
流只能消费一次:流被终端操作消费后不可重复使用。
避免副作用:不要在 forEach 中修改外部变量(推荐使用不可变对象)。
性能权衡:小数据集优先用顺序流,大数据集考虑并行流。
资源管理:使用 try-with-resources 管理需要关闭的流(如 Files.lines)。
掌握这些操作可显著提升集合处理的简洁性和效率!

浙公网安备 33010602011771号