前言
Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。让程序员写出高效率、干净、简洁的代码。
什么是 Stream?
Stream(流)是一个来自数据源的元素队列并支持聚合操作,流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。 Stream(流)的组成包含:元素、数据源、聚合操作、内部迭代、Pipelining等。
- 元素:特定类型的对象
- 数据源:流的来源,元素的集合,数组等。
- 聚合操作:类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
- 内部迭代:在流中内部迭代,与for外部处理不同。
- Pipelining: 中间操作都会返回流对象本身。
Stream 基本操作
初始化两组数据
List<String> stringList = Arrays.asList("juejin", "zijie", "toutiao", "feidian", "join","", "juelimanman");
List<Integer> integerList = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7,8, 9, 10,11,12);
Stream 创建
stream()
使用stream()创建串行流。
Stream<String> stream = stringList.stream();
parallelStream()
parallelStream() 方法创建并行流
Stream<String> stringStream = stringList.parallelStream();
Arrays.stream()
使用Arrays 中的 stream() 方法
Stream<String> stream1 = Arrays.stream(new String[10]);
Stream.of
Stream.of创建流,创建的是有限流
Stream<String> streamOf = Stream.of("juejin", "zijie", "toutiao", "feidian", "join","", "juelimanman");
Stream.iterate
Stream.iterate创建流,创建一个有序无限的数据流
Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(5);
Stream.generate
Stream.generate创建流,创建一个无限数据流
Stream<Double> stream3 = Stream.generate(Math::random).limit(2);
reader.lines
使用 BufferedReader.lines() 方法,将每行内容转成流
Stream<String> lineStream = reader.lines();
Stream 操作
forEach
forEach来迭代流中的每个数据,输出所有元素
stringList.forEach(System.out::println);
map
map 方法用于映射每个元素到对应的结果
stringList.stream().map(i->i.equals("juejin"));
flatMap
flatMap:将流中的每个值都换成另一个流,然后把所有流连接成一个流。
stream.flatMap(String::toUpperCase).collect(Collectors.toList());
filter
filter 方法用于通过设置的条件过滤出元素,过滤流中的某些元素
stringList.stream().filter(i->i.equals("juejin"));
peek
如同于map,能得到流中的每一个元素。但map接收的是一个Function表达式,有返回值;而peek接收的是Consumer表达式,没有返回值。
stream.peek(s -> s.equals("juejin"));
limit
limit(n) 方法用于获取指定数量的流。例如:limit(n):获取n个元素
integerList.stream().limit(3);
skip
skip(n):跳过n元素,配合limit(n)可实现分页
integerList.stream().skip(5).limit(3);
distinct
distinct:通过流中元素的 hashCode() 和 equals() 去除重复元素
integerList.stream().distinct().collect(Collectors.toList());
sorted
sorted sorted 方法用于对流进行排序,自然排序。
integerList.stream().sorted();
sorted(Comparator com)
sorted(Comparator com):定制排序,自定义Comparator排序器
integerList.stream().sorted(Comparator.comparing(Integer::intValue));
parallel
parallelStream 是流并行处理程序的代替方法。
integerList.parallelStream().sorted();
Collectors
Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。
stringList.stream().filter(s -> s.equals("juejin")).collect(Collectors.toList());
count
count 统计结果的收集器也非常有用,流的终止操作,用在流的最后。
integerList.stream().count();
allMatch
allMatch:接收一个函数,当流中每个元素都符合该断言时才返回true,否则返回false,流的终止操作,用在流的最后
integerList.stream().allMatch(integer -> integer>0);
noneMatch
noneMatch:接收一个函数,当流中每个元素都不符合该断言时才返回true,否则返回false,流的终止操作,用在流的最后。
integerList.stream().noneMatch(integer -> integer>100);
anyMatch
anyMatch:接收一个函数,只要流中有一个元素满足该断言则返回true,否则返回false,流的终止操作,用在流的最后。
integerList.stream().anyMatch(integer -> integer>2);
findFirst
findFirst:返回流中第一个元素,流的终止操作,用在流的最后。
stringList.stream().findFirst();
findAny
findAny:返回流中的任意元素,流的终止操作,用在流的最后。
stringList.stream().findAny();
max
max:返回流中元素最大值,流的终止操作,用在流的最后。
userList.stream().max(Comparator.comparingInt(user::score));
min
min:返回流中元素最小值,流的终止操作,用在流的最后。
userList.stream().min(Comparator.comparingInt(user::score));
collect
collect:接收一个Collector实例,将流中元素收集成另外一个数据结构。
integerList.stream().filter(u->user.getScore>60).collect(Collectors.toList());
总结
Stream API 提供了一种高效且易于使用的处理数据的方式。让程序员写出高效率、干净、简洁的代码。在Stream流中都是使用复杂的表达式去处理数据逻辑,当然大家可以先了解这些方法,在项目中使用到的时候,再进行深入了解,进行更复杂的组合操作。