Stream API是Java 8引入的函数式编程特性,提供了一种高效处理集合数据的方式。以下是Stream流处理的常用操作示例。
![图片[1]_Java Stream流处理示例小结_知途无界](https://zhituwujie.com/wp-content/uploads/2025/06/d2b5ca33bd20250608112005.png)
一、基础操作
1. 创建Stream
// 从集合创建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream1 = list.stream();
// 从数组创建
String[] array = {"a", "b", "c"};
Stream<String> stream2 = Arrays.stream(array);
// 直接创建
Stream<String> stream3 = Stream.of("a", "b", "c");
// 创建无限流
Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 1);
2. 中间操作
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// 过滤
Stream<String> filtered = names.stream()
.filter(name -> name.length() > 4);
// 映射
Stream<Integer> nameLengths = names.stream()
.map(String::length);
// 去重
Stream<String> distinct = names.stream()
.distinct();
// 排序
Stream<String> sorted = names.stream()
.sorted();
// 限制数量
Stream<String> limited = names.stream()
.limit(2);
// 跳过元素
Stream<String> skipped = names.stream()
.skip(1);
3. 终端操作
// 遍历
names.stream().forEach(System.out::println);
// 收集为List
List<String> collectedList = names.stream()
.filter(name -> name.startsWith("A"))
.collect(Collectors.toList());
// 收集为Set
Set<String> collectedSet = names.stream()
.collect(Collectors.toSet());
// 连接字符串
String joined = names.stream()
.collect(Collectors.joining(", "));
// 计数
long count = names.stream().count();
// 匹配检查
boolean anyMatch = names.stream()
.anyMatch(name -> name.startsWith("A"));
boolean allMatch = names.stream()
.allMatch(name -> name.length() > 3);
boolean noneMatch = names.stream()
.noneMatch(name -> name.length() > 10);
// 查找元素
Optional<String> first = names.stream().findFirst();
Optional<String> any = names.stream().findAny();
// 归约操作
Optional<String> longestName = names.stream()
.reduce((name1, name2) ->
name1.length() > name2.length() ? name1 : name2);
二、高级操作
1. 数值流处理
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 转换为IntStream
IntStream intStream = numbers.stream()
.mapToInt(Integer::intValue);
// 求和
int sum = intStream.sum();
// 平均值
OptionalDouble avg = numbers.stream()
.mapToInt(Integer::intValue)
.average();
// 最大值
OptionalInt max = numbers.stream()
.mapToInt(Integer::intValue)
.max();
// 数值范围
IntStream range = IntStream.range(1, 5); // 1,2,3,4
IntStream rangeClosed = IntStream.rangeClosed(1, 5); // 1,2,3,4,5
2. 分组和分区
class Person {
String name;
int age;
String city;
// 构造方法、getter/setter省略
}
List<Person> people = Arrays.asList(
new Person("Alice", 23, "New York"),
new Person("Bob", 30, "New York"),
new Person("Charlie", 28, "London"),
new Person("David", 30, "London")
);
// 按城市分组
Map<String, List<Person>> byCity = people.stream()
.collect(Collectors.groupingBy(Person::getCity));
// 按年龄分组并统计人数
Map<Integer, Long> countByAge = people.stream()
.collect(Collectors.groupingBy(
Person::getAge,
Collectors.counting()
));
// 分区(按条件分为true/false两组)
Map<Boolean, List<Person>> partitioned = people.stream()
.collect(Collectors.partitioningBy(
p -> p.getAge() > 25
));
// 多级分组
Map<String, Map<Integer, List<Person>>> byCityAndAge = people.stream()
.collect(Collectors.groupingBy(
Person::getCity,
Collectors.groupingBy(Person::getAge)
));
3. 并行流处理
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// 创建并行流
Stream<String> parallelStream = names.parallelStream();
// 并行处理示例
List<String> upperCaseNames = names.parallelStream()
.map(String::toUpperCase)
.collect(Collectors.toList());
// 注意:并行流不保证顺序
List<String> unordered = names.parallelStream()
.map(String::toUpperCase)
.collect(Collectors.toList());
// 保持顺序的并行处理
List<String> ordered = names.parallelStream()
.map(String::toUpperCase)
.collect(Collectors.toList());
三、实用示例
1. 文件处理
// 读取文件行
try (Stream<String> lines = Files.lines(Paths.get("data.txt"))) {
List<String> filteredLines = lines
.filter(line -> line.contains("error"))
.collect(Collectors.toList());
} catch (IOException e) {
e.printStackTrace();
}
// 遍历目录
try (Stream<Path> paths = Files.walk(Paths.get("/path/to/dir"))) {
List<Path> javaFiles = paths
.filter(Files::isRegularFile)
.filter(p -> p.toString().endsWith(".java"))
.collect(Collectors.toList());
} catch (IOException e) {
e.printStackTrace();
}
2. 集合转换
// List转Map
Map<String, Integer> nameToLength = names.stream()
.collect(Collectors.toMap(
Function.identity(), // key
String::length // value
));
// 处理重复key
Map<String, Person> personByName = people.stream()
.collect(Collectors.toMap(
Person::getName,
Function.identity(),
(existing, replacement) -> existing // 解决key冲突
));
3. 复杂对象处理
// 获取所有城市列表
List<String> cities = people.stream()
.map(Person::getCity)
.distinct()
.collect(Collectors.toList());
// 统计每个城市的平均年龄
Map<String, Double> avgAgeByCity = people.stream()
.collect(Collectors.groupingBy(
Person::getCity,
Collectors.averagingInt(Person::getAge)
));
// 获取年龄最大的三个人
List<Person> top3Oldest = people.stream()
.sorted(Comparator.comparingInt(Person::getAge).reversed())
.limit(3)
.collect(Collectors.toList());
四、性能注意事项
- 避免在流中执行耗时操作:流操作应保持简单高效
- 合理使用并行流:数据量大且处理复杂时使用
- 避免重复使用流:流一旦被消费就不能再次使用
- 优先使用方法引用:比lambda表达式更简洁高效
- 注意自动装箱:数值操作优先使用原始类型流(IntStream等)
五、常见问题解决方案
1. 处理空集合
List<String> names = getNames(); // 可能返回null
List<String> nonNullNames = Optional.ofNullable(names)
.orElse(Collections.emptyList())
.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList());
2. 多层集合扁平化
List<List<String>> nestedList = Arrays.asList(
Arrays.asList("a", "b"),
Arrays.asList("c", "d")
);
List<String> flatList = nestedList.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
3. 自定义收集器
// 收集为不可变列表
List<String> immutableList = names.stream()
.collect(Collectors.collectingAndThen(
Collectors.toList(),
Collections::unmodifiableList
));
// 自定义统计收集器
IntSummaryStatistics stats = people.stream()
.collect(Collectors.summarizingInt(Person::getAge));
Stream API极大地简化了集合操作代码,使数据处理更加直观和高效。掌握这些常用模式可以显著提高Java开发效率。
© 版权声明
文中内容均来源于公开资料,受限于信息的时效性和复杂性,可能存在误差或遗漏。我们已尽力确保内容的准确性,但对于因信息变更或错误导致的任何后果,本站不承担任何责任。如需引用本文内容,请注明出处并尊重原作者的版权。
THE END

























暂无评论内容