JDK8-Stream流库详解

流提供了一种让我们可以在比集合更高的概念级别上指定计算的数据视图。通过使用流,我们可以说明想要完成什么任务,而不是说明如何去实现它。

流的创建

  • Collection.stream():从一个集合生成流
  • Collection.parallelStream():从一个集合生成并行流
  • Stream::of(T... t):从一个或多个元素中生成流
  • Arrays::stream(T[] array, int startInclusive, int endExclusive):从数组中生成流
  • Stream::empty():生成一个空的流
String str = "1,2,3,4,5,6,7";
Stream<String> wordStream1 = Stream.of(words);
//等效于
Stream<String> wordStream2 = Arrays.stream(words, 0, words.length);

无限流

  1. Stream::generate(Supplier<T> s),通过supplier的get获取流下一个要生成的元素。
Stream<String> echos = Stream.generate(() -> "Echo");
Stream<Double> randoms = Stream.generate(Math::random);
  1. Stream::iterate(final T seed, final UnaryOperator<T> f),接受一个种子值和一个一元函数,从种子值开始反复将函数应用到之前的结果上。
Stream<BigInteger> integers 
    = Stream.iterate(BigInteger.ZERO,n->n.add(BigInteger.ONE));

流的修改

流的操作不会修改其数据源,当我们想修改流中的数据时,只能通过一些方法获取一个中间流。

过滤

Stream<T> filter(Predicate<? super T> predicate)

用于过滤掉一些数据,只保留predicate.test()返回为true的数据。

Stream<Integer> nums = Stream.of(1,2,3,4,5,6,7);
Stream<Integer> modNums = nums.filter(i -> i > 4); //5,6,7

转换

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

当我们想按照某种方式转换流中的的值可以使用map并传递执行该转换的函数。

Stream<Integer> nums = Stream.of(1,2,3,4,5,6,7);
Stream<Integer> modNums = nums.map(i -> i + 3); //4,5,6,7,8,9,10

其他操作

  • Stream<T> limit(long maxSize):截取最大maxSize个元素,组成新流。
  • Stream<T> skip(long n):丢弃前n个元素,组成新流。
  • public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b):产生一个流,它的元素是a的元素后面跟了b的元素。
  • Stream<T> distinct():去除重复操作
  • Stream<T> sorted()Stream<T> sorted(Comparator<? super T> comparator):返回一个排序后的流。
  • Stream<T> peek(Consumer<? super T> action):当实际访问一个元素时,会把函数应用到这个元素。(仅当访问时,因为流的操作是懒惰的)

流的约简

约简是一种终结操作,它们会将流约简为可以在程序中使用的非流值。

  • long count(); :返回流中元素的数量
  • Optional<T> max(Comparator<? super T> comparator);:返回最大值
  • Optional<T> min(Comparator<? super T> comparator);:返回最小值
  • Optional<T> findFirst();:返回第一个值,搭配filter使用有奇效
  • Optional<T> findAny();:返回任意一个值,适用于并行处理流
  • boolean anyMatch(Predicate<? super T> predicate);:是否存在匹配
  • boolean allMatch(Predicate<? super T> predicate);:是否全部匹配
  • boolean noneMatch(Predicate<? super T> predicate);:是否不存在匹配

需要注意的是部分方法返回的是一个Optional<T>类型的返回值,它要么在其中包装了答案,要么表示没有任何值(因为流碰巧为空)。

Optional有如下主要方法:

public boolean isPresent();//检查值是否存在
public T get();//如果有值返回值,没有抛出异常
public T orElse(T other);//如果有值返回值,没有值返回给定的参数

收集结果

  • 调用iterator()返回一个旧式风格的迭代器
  • 使用forEach()方法传入一个一元操作方法。
  • toArray()返回一个Object数组
  • <R, A> R collect(Collector<? super T, A, R> collector);传入一个collector,返回集合,常用的有Collectors.toList()Collectors.toSet()
    或者Collectors.toCollection()里面传入具体集合的构造器方法

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/jdk8-stream%e6%b5%81%e5%ba%93%e8%af%a6%e8%a7%a3/

发表评论

电子邮件地址不会被公开。