Java 8 引入了 Stream API,它提供了一种高效且易于表达的方式来处理集合数据。Stream API 允许你以声明式的方式处理数据,支持函数式编程风格,使得代码更加简洁和易读。以下是关于 Java Stream 流的详细介绍:
1. Stream 流的基本概念
Stream 流是对集合(Collection)数据进行操作的抽象,它可以进行各种操作,如过滤、映射、排序、聚合等。Stream 流不是数据结构,它不存储数据,而是通过管道(pipeline)的方式对数据进行处理。
2. Stream 流的创建
2.1 从集合创建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
2.2 从数组创建
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);
2.3 使用 Stream.of
创建
Stream<String> stream = Stream.of("a", "b", "c");
2.4 创建无限流
Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2);
3. Stream 流的操作
Stream 流的操作分为两种类型:中间操作(intermediate operations)和终端操作(terminal operations)。
3.1 中间操作
中间操作返回一个新的 Stream 流,可以进行链式调用。常见的中间操作包括:
- filter:过滤元素
- map:映射元素
- flatMap:扁平化映射
- distinct:去重
- sorted:排序
- peek:调试操作
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> filteredNames = names.stream()
.filter(name -> name.length() > 3)
.map(String::toUpperCase)
.collect(Collectors.toList());
3.2 终端操作
终端操作触发流的处理并产生结果。常见的终端操作包括:
- forEach:遍历元素
- collect:收集元素到集合
- reduce:聚合操作
- count:计数
- anyMatch:任意匹配
- allMatch:全部匹配
- noneMatch:无匹配
- findFirst:查找第一个元素
- findAny:查找任意元素
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.filter(n -> n % 2 == 0)
.reduce(0, Integer::sum);
4. Stream 流的特性
4.1 惰性求值
Stream 流的操作是惰性求值的,即直到终端操作时才会真正执行。这样可以提高性能,避免不必要的计算。
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5)
.filter(n -> {
System.out.println("Filter: " + n);
return n % 2 == 0;
});
System.out.println("Before terminal operation");
stream.forEach(System.out::println);
4.2 并行流
Stream 流支持并行处理,通过 parallelStream
方法可以创建并行流,利用多核处理器提高处理速度。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.parallelStream()
.filter(n -> n % 2 == 0)
.reduce(0, Integer::sum);
5. Stream 流的示例
5.1 过滤和映射
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> filteredNames = names.stream()
.filter(name -> name.length() > 3)
.map(String::toUpperCase)
.collect(Collectors.toList());
5.2 去重和排序
List<Integer> numbers = Arrays.asList(5, 3, 1, 4, 2, 3, 5);
List<Integer> distinctSortedNumbers = numbers.stream()
.distinct()
.sorted()
.collect(Collectors.toList());
5.3 聚合操作
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.filter(n -> n % 2 == 0)
.reduce(0, Integer::sum);
5.4 分组和统计
List<Person> people = Arrays.asList(
new Person("Alice", 25),
new Person("Bob", 30),
new Person("Charlie", 25)
);
Map<Integer, List<Person>> peopleByAge = people.stream()
.collect(Collectors.groupingBy(Person::getAge));
Map<Integer, Long> countByAge = people.stream()
.collect(Collectors.groupingBy(Person::getAge, Collectors.counting()));
6. Stream 流的注意事项
6.1 避免修改流的数据源
在流操作过程中,应避免修改流的数据源,否则可能导致不确定的行为。
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
Stream<String> stream = list.stream();
list.add("d"); // 避免在流操作过程中修改数据源
stream.forEach(System.out::println);
6.2 避免多次使用同一个流
流一旦被终端操作消费,就不能再次使用。
Stream<String> stream = Stream.of("a", "b", "c");
stream.forEach(System.out::println);
stream.forEach(System.out::println); // 会抛出 IllegalStateException
7. 总结
Java Stream API 提供了一种强大且灵活的方式来处理集合数据。通过 Stream 流,你可以以声明式的方式进行数据处理,支持惰性求值和并行处理,使得代码更加简洁和高效。希望这些内容能够帮助你更好地理解和应用 Java Stream 流。
标签:Java,Stream,stream,Arrays,List,---,操作,asList From: https://blog.csdn.net/xycxycooo/article/details/140881688