Java8中stream的使用

Java8中的stream

为什么需要stream

  • Stream API借助于同样新出现的Lambda表达式,极大的提高编程效率和程序可读性。
  • 提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用fork/join并行方式来拆分任务和加速处理过程。

概述

不保存数据。

操作类型分为两种:Intermediate(中间操作), Terminal(结束操作)

  • Intermediate:一个流可以后面跟随零个或多个intermediate操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。这类操作都是惰性化的(lazy),就是说,仅仅调用到这类方法,并没有真正开始流的遍历。
  • Terminal:一个流只能有一个terminal操作,当这个操作执行后,流就被使用“光”了,无法再被操作。所以,这必定是流的最后一个操作。Terminal操作的执行,才会真正开始流的遍历,并且会生成一个结果,或者一个副作用。
  • 无状态:指元素的处理不受之前元素的影响;
  • 有状态:指该操作只有拿到所有元素之后才能继续下去。

常见用法

创建

stream()和parallelStream()

  • stream创建顺序流
  • parallelStream 创建并行流

stream中的静态方法 of()、iterate()、generate()

  • Stream<Integer> stream = Stream.of(1,2,2,4,5,6);
  • Stream<Integer> stream = Stream.iterate(1, (x) -> x + 2).limit(6);//1,3,5,7,9,11
  • Stream<Double> stream = Stream.generate(Math::random).limit(3);//3个随机数

Arrays.stream()将array转流

String[] array = new String[] {"a", "b"};
Stream stream = Arrays.stream(array);

Pattern.splitAsStream() 将字符串分隔成流

Pattern pattern = Pattern.compile(",");
Stream<String> stream = pattern.splitAsStream("a,b,c");

映射

map

  • 1:1映射,每个元素按一定规则(lambda表达式)转换成另一个元素。

flatMap

  • 1:n映射,每个元素都转换成另一个流,然后把所有流连成一个流。
Stream<List<Integer>> stream = Stream.of(Arrays.asList(1), Arrays.asList(2,3), Arrays.asList(4,5,6));
Stream<Integer> out = stream.flatMap((s) -> s.stream()); //out里没有List

筛选与切片

  • filter(lambda):(按lambda表达式)过滤流中的某些元素
  • limit(n):获取n个元素
  • skip(n):跳过n元素,配合limit(n)可实现分页
  • distinct:通过流中元素的 hashCode() 和 equals() 去除重复元素

排序

可以先对流内容处理后再排序,减少排序时间

  • sorted():自然排序,流中元素需实现Comparable接口。(String类等已实现Comparable接口)
  • sorted(Comparator com):定制排序,自定义Comparator排序器
    xxx.stream.sorted((o1,o2) -> xxx);

消费

  • 无法对一个Stream执行两次Terminal运算,但peek可以达到上述目的。
  • peek无返回值,对每个元素执行操作并返回一个新的Stream
Stream.of("one", "two", "three", "four").filter(e -> e.length() > 3)
 .peek(e -> System.out.println("Filtered value: " + e)).map(String::toUpperCase)
 .peek(e -> System.out.println("Mapped value: " + e)).collect(Collectors.toList());

匹配、聚合

  • allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true
  • noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true
  • anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true
  • findFirst:返回流中第一个元素
  • findAny:返回流中的任意(一个)元素
  • count:返回流中元素的总个数
  • max/min:返回流中元素最大/小值
List<Integer> list = Arrays.asList(1,2,3,4,5);
Integer max = list.stream().max(Integer::compareTo).get();
Integer min = list.stream().min(Integer::compareTo).get();

收集

  • 可以转成list(toList),set(toSet),map(toMap,key不能相同)
  • 可以加入字符串分隔符
    Collectors.joining(",", "(", ")")//(aa,bb,cc)

参考

posted @ 2021-12-27 17:21  zjcfrancis  阅读(188)  评论(0编辑  收藏  举报