【收藏】Java8的Stream玩法大全

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

前言

  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流中都是使用复杂的表达式去处理数据逻辑,当然大家可以先了解这些方法,在项目中使用到的时候,再进行深入了解,进行更复杂的组合操作。

  作者介绍:【小阿杰】一个爱鼓捣的程序猿,JAVA开发者和爱好者。公众号【Java全栈架构师】维护者,欢迎关注阅读交流。

  好了,感谢您的阅读,希望您喜欢,如对您有帮助,欢迎点赞收藏。如有不足之处,欢迎评论指正。下次见。