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/

(0)
彭晨涛彭晨涛管理者
上一篇 2020年2月11日
下一篇 2020年2月12日

相关推荐

  • 常用开源数据库连接池C3P0、Druid介绍

    概述 很多时候,连接的混乱管理所造成的系统资源开销过大成为制约大型企业级应用效率的瓶颈。因为每一次WEB请求都要建立一次数据库连接,建立连接是一个耗费资源的活动,每次都得花费0.0…

  • ArrayList源码分析

    总结 总结放前面防止太长不看: ArrayList内部是用数组实现的。 如果使用无参构造函数建立ArrayList,在添加第一个元素的时候会分配10个元素的空间。 ArrayLis…

    2019年11月22日
    0160
  • AQS及其应用ReentrantLock源码分析

    AQS原理 概述 全称是 AbstractQueuedSynchronizer(抽象同步队列),是阻塞式锁和相关的同步器工具的框架。 特点:+ 用 state 属性来表示资源的状态…

    2020年2月4日
    0120
  • 深入理解java虚拟机第三版读书笔记05

    续深入理解java虚拟机第三版读书笔记04 HotSpot的算法细节实现 根节点枚举 如何高效的找出所有GC Roots? 迄今为止,所有收集器在根节点枚举这一步骤时都是必须暂停用…

    2020年1月12日
    0570
  • NIO网络编程之Selector介绍

    Selector 要实现异步IO要通过Selector,甚至我们可以通过一个线程管理多个Channel的读写,这是NIO相较BIO的优越之处之一。 Channel可以注册到一个Se…

    Java 2020年2月7日
    0760
  • AbstractCollection默认集合类

    AbstractCollection用于实现基本的Collection结构,提供给普通用户继承使用。也是JDK集合类的父类,部分方法是没有被重载的。 相比Collection接口并…

    Java 2019年11月18日
    0100
  • 阻塞队列BlockingQueue详解

    阻塞队列是生产者消费者模式的经典体现。 我们在曾在Java线程池详解中自己实现过一个阻塞队列,这篇文章我们来研究一下JDK中的阻塞队列: BlockingQueue接口主要方法 抛…

    Java 2020年2月14日
    0590
  • 按键排序的Map-TreeMap源码分析

    总结 总结放前面(这篇挺短的)1. TreeMap基于红黑树实现,可以对Map中的key排序2. 它的排序和定位需要依赖比较器或实现 Comparable 接口,也因此不需要key…

    Java 2020年2月16日
    0130
  • Servlet4.0初识总结

    JavaEE8 JavaEE8,是自2013年6月Java企业版的首次更新。JAVAEE8提供了一些新的API,提供了对HTTP/2的新支持。 Servlet4.0 Servlet…

    Java 2019年11月28日
    02070
  • 深入理解java虚拟机第三版读书笔记13

    以下是第十三章 Java内存模型与线程的内容 线程安全 当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任…

    2020年1月30日
    0130

发表回复

登录后才能评论