Stream 流
2024年10月28日
介绍
Java 8 API添加了一个新的抽象称为流Stream,可以以一种声明的方式处理数据。Stream流使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。流的特点有:
- 不是数据结构,不会保存数据,只是在原数据集上定义了一组操作
- 惰性求值,流在中间处理过程中,只是对操作进行了记录,并不会立即执行,需要等到执行终止操作的时候才会进行实际的计算
- Stream不保存数据,它会将操作后的数据保存到另外一个对象中
基本使用
创建
public class StreamAPI {
public static void main(String[] args) throws FileNotFoundException {
// 1. 数组
Integer[] array = {1, 2, 3};
Stream<Integer> integerStream1 = Arrays.stream(array);
// 2. 集合
List<Integer> list = Arrays.asList(array);
Stream<Integer> listStream1 = list.stream();
Stream<Integer> listStream2 = list.parallelStream();
// 3. BufferedReader -------------------------------
BufferedReader reader = new BufferedReader(new FileReader("xxx"));
Stream<String> linesStream = reader.lines();
// 4. 字符串处理
String str = "1,2,3";
Pattern pattern = Pattern.compile(",");
Stream<String> stringStream = pattern.splitAsStream(str);
// 4. Stream自带的静态方法
Stream<Integer> integerStream = Stream.of(1, 2, 3);
Stream<Integer> integerStream2 = Stream.iterate(1, s -> (s + 2));
Stream<Double> generate = Stream.generate(Math::random);
}
}
操作
Stream 的操作分为两类:
- 中间操作(Intermediate):可以有多个,每次返回一个新的流,可进行链式操作
- 有状态:只有拿到所有元素之后才能获得结果
- 无状态:操作不受之前元素的影响
- 结束操作(Terminal):触发 Stream 进行计算的操作,只能有一个。每次执行完,这个流也就用完了,无法继续执行操作
- 短路:满足短路条件时,不需要处理完所有元素就能返回结果
- 非短路:处理完所有元素才返回结果
名称 | 类型 | 返回类型 | 使用的类型/函数式接口 | 函数描述 |
---|---|---|---|---|
filter | 中间操作(Intermediate) | Stream | Predicate | T -> boolean |
distinct | 中间操作(Intermediate)、有状态 | Stream | 无 | T -> boolean |
skip | 中间操作(Intermediate)、有状态 | Stream | 无 | 无 |
limit | 中间操作(Intermediate) | Stream | 无 | 无 |
map | 中间操作(Intermediate) | Stream | Function | T -> R |
flatMap | 中间操作(Intermediate) | Stream | Function | T -> Stream |
sorted | 中间操作(Intermediate)、有状态 | Stream | Comparator | (T, T) -> int |
noneMatch | 结束操作(Terminal) | boolean | Predicate | T -> boolean |
allMatch | 结束操作(Terminal) | boolean | Predicate | T -> boolean |
findAny | 结束操作(Terminal) | Optional | 无 | 无 |
findFirst | 结束操作(Terminal) | Optional | 无 | 无 |
forEach | 结束操作(Terminal) | void | Consumer | T -> void |
collect | 结束操作(Terminal) | R | Collector | 无 |
reduce | 结束操作(Terminal) | Optional | BinaryOperator | (T, T) -> T |
count | 结束操作(Terminal) | long | 无 | 无 |
User user1 = new User(1,"张三");
User user2 = new User(2,"李四");
User user3 = new User(3,"王五");
ArrayList<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
users.add(user3);
// list
List<Integer> list = integerStream1.collect(Collectors.toList());
// set
Set<Integer> set = integerStream1.collect(Collectors.toSet());
// map key不能相同
Map<Integer, String> map = users.stream().collect(Collectors.toMap(User::getId, User::getName));
// 获取users元素个数
Long count = users.stream().collect(Collectors.counting());
// 获取users集合id最大值
Optional<Integer> max = users.stream().map(User::getId).collect(Collectors.maxBy(Integer::compare));
// 获取users集合id最小值
Optional<Integer> min = users.stream().map(User::getId).collect(Collectors.minBy(Integer::compare));
// 获取users集合所有id的和
Integer id = users.stream().collect(Collectors.summingInt(User::getId));
// 获取users集合所有id的平均值
Double average = users.stream().collect(Collectors.averagingDouble(User::getId));