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日

相关推荐

  • 深入理解java虚拟机第三版读书笔记07

    附: Java虚拟机规范-Java虚拟机指令集:JDK8 Java虚拟机规范-Java虚拟机指令集:JDK13 续深入理解java虚拟机第三版读书笔记06 字节码指令简介 Java…

    Java 2020年1月21日
    0230
  • Java之UDP编程

    DatagramSocket概述 上次在Java网络套接字Socket编程那篇博客里只写了Socket和ServerSocket,即TCP通信,这次来补充一下UDP通信。 和Soc…

    Java 2020年3月11日
    0820
  • Java多线程基础

    多线程应用 异步调用 以调用方角度来讲,如果+ 需要等待结果返回,才能继续运行就是同步+ 不需要等待结果返回,就能继续运行就是异步 同步在多线程中还有另外一个意思,是让多个线程步调…

    2020年1月31日
    0350
  • 按键排序的Map-TreeMap源码分析

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

    Java 2020年2月16日
    0130
  • Java8避免空指针异常Optional类的使用

    最近都是一天写一篇算法题解,好久没有写过博客了,不知道写啥了而且快到期末考试了。。 今天介绍一个Java8的特性:Optional类,这个类我平时也不咋用,今天来研究一下。 Opt…

    Java 2020年6月3日
    0660
  • 深入理解java虚拟机第三版读书笔记04

    以下是第三章 垃圾收集器与内存分配策略的内容 概述 程序计数器、虚拟机栈、本地方法栈是线程独有的,栈帧更是随方法结束而消亡,不需要垃圾回收。而堆和方法区则需要经过垃圾回收的设计 对…

    2020年1月8日
    0320
  • ThreadPoolExecutor源码分析-线程池如何实现线程复用?

    线程的复用问题 在开始看线程池的源码之前,先来看这么一个问题: 一个Thread对象可以重复地调用start()方法吗? 试试就知道了: @Test public void tes…

    2020年5月21日
    02880
  • HashMap源码分析

    HashMap是java中非常常见的一个数据结构,在这篇文章里,我依然以Map中的操作为导向来循序渐进研究HashMap中的源码,阅读这篇文章需要的前置知识有: 弱平衡的二叉查找树…

    Java 2020年2月12日
    0240
  • 数据库理论之OLTP与OLAP

    OLTP OLTP 即联机事务处理,就是我们经常说的关系数据库,意即记录即时的增、删、改、查,就是我们经常应用的东西,主要供基层人员使用,进行一线业务操作,这是数据库的基础。 对于…

    项目/编程理论 2020年2月16日
    0310
  • 深入理解java虚拟机第三版读书笔记02

    以下是第二章 Java内存区域与内存溢出异常的内容 运行时数据区域 程序计数器 特点 程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。 程序计数器是…

    2020年1月5日
    0210

发表回复

登录后才能评论