转载

Java8 Stream API 详细使用方法与操作技巧指南

本文实例讲述了Java8 Stream API 详细使用方法与操作技巧。分享给大家供大家参考,具体如下:

1. 概述

Java 8 引入的一个重要的特性无疑是 Stream API。Stream 翻译过来是“流”,突然想到的是大数据处理有个流式计算的概念,数据通过管道经过一个个处理器(Handler)进行筛选,聚合,而且流都具有向量性,强调的是对数据的计算处理,而集合强调的是数据集。Stream可以看做是一个可操作的数据集序列,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。有点类似于数据库中的增删改查操作。十分高效而且易于使用。

2. 创建Stream

从不同的数据源创建流有很多方式。 被创建的流并不能改变数据源。什么意思呢?打个比方,从一个集合创建流后,对流的操作并不会改变这个集合的数据状态。我们还是举个例子吧。

如上图, 我们将一个长度为3的集合放入一个流,过滤掉元素长度不超过4的元素,然后把剩下的迭代出来。同时我们还打印一下原始的数据源 strArr 集合长度看看是否发生了变化。结果虽然从流中移除了 java 这个元素但是 strArr 却并没有变化。

接下来我们开始梳理一下创建流的方式。

2.1 空流

你应该注意到上图中我用 Collections 创建了一个空的 List ,流也是一样,而且这两者的意义也是一样的。都是避免为没有元素而返回 null

2.2 从集合创建流

上面摘自java 8 Collection<E> 说明只要是 Collection<E> 的实现都可以创建流。

2.3 从数组创建流

我们可以从数组来创建一个流,或者从数组中按照索引截取一部分创建流

2.4 通过构造器创建流

Stream 提供建造者方法来构建流。不过请注意泛型约束,否则返回的是Object类型的流。

2.5 无限流

generate() 方法接收 Supplier<T> 函数来生成元素,而且生成如果不加以限制将不会停止,直到内存限制。下面这个例子将生成长度为10,字符串元素长度为5的字符串流

创建无限流的另一种方法是使用 iterate() 方法。和 generate() 方法一样都要加以限制。不同的是 iterate()方法第一个参数作为起始的种子,第二个函数参数来定制生成元素的规则。下面这个例子是从1作为第一个元素,每个元素在上一个元素的基础上加1,限制长度为10。下面将打印1-10。

2.6 基本类型流

Java 8提供了从三种基本类型创建流的可能性:int,long和double。由于Stream <T>是一个通用接口,并且无法使用基本类型作为泛型的类型参数,因此创建了三个新的特殊接口: IntStreamLongStreamDoubleStream

使用这些新的API避免了不必要的自动装箱,从而提高了生产率:

以上两个方法的起始都是从1开始,步长为1创建序列。区别就是 endExclusive=3 range 方法不包含3,而 rangeClosed 包括3。

从Java 8开始, Random 类为生成基本类型流提供了广泛的方法。例如,以下代码创建一个 DoubleStream ,它有三个随机 double 元素:

2.7 字符串流

String也可以用作创建流的源。借助String类的 chars() 方法。由于没有 CharStream ,在JDK的 IntStream 用于表示字符流代替。

以下示例根据指定的 RegExString 拆分为子字符串:

2.8 文件流

Java NIO类 Files 允许通过 lines() 方法生成文本文件的 Stream <String> 。文本的每一行都成为流的一个元素:

你还可以在 lines() 方法中指定字符集编码。

2.9 并行流

并行流就是把一个内容分成多个数据块,并用不同的线程分成多个数据块,并用不同的线程分别处理每个数据块的流。底层用了Fork/Join框架。该流主要用来处理大批量的数据源。少量数据不建议使用。带有parallel的声明方式都是并行流,这里不在介绍。

但是使用一定要注意数据并行处理同步。要么使用同步集合,诸如 Collections.synchronized 系列。或者在并行流收集元素到集合中时,调用 collect 方法,一定不要采用 Foreach 方法或者 map 方法。

3.流的引用

只要只调用中间操作,就可以实例化一个流并具有对它的可访问引用。执行终端操作会使流不可访问。从技术上讲,以下代码看上去是有效的:

第3行是终端操作 如果接着执行第4行对stream进行重用将触发 IllegalStateException 。一定要谨记 Java 8 中同一个Stream 在终端操作后是不能重用的。 正确的做法是这样的:

4.流的中间操作

中间操作就是对数据源中的数据的计算操作。其实上面我们已经对流进行很多的中间操作比如 filter()limit() 等等。网上很著名的一些中间操作讲解

5.流的生命周期

创建Stream 一个数据源(如:集合、数组),获取一个流中间操作 一个中间操作链,对数据源的数据进行处理终止操作(终端操作)一个终止操作,执行中间操作链,并产生结果,到此整个流消亡。

6.总结

Java 8 Stream 具有里程碑的意义。改变了以往对数据处理的模式。通过本篇对流以及流的生命周期都做了详尽的说明。相信你已经能够通过Stream来提高你的开发效率。

更多关于java算法相关内容感兴趣的读者可查看本站专题:《Java文件与目录操作技巧汇总》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。

时间:2020-05-20

Java8新特性Stream流实例详解

什么是Stream流? Stream流是数据渠道,用于操作数据源(集合.数组等)所生成的元素序列. Stream的优点:声明性,可复合,可并行.这三个特性使得stream操作更简洁,更灵活,更高效. Stream的操作有两个特点:可以多个操作链接起来运行,内部迭代. Stream可分为并行流与串行流,Stream API 可以声明性地通过 parallel() 与sequential() 在并行流与顺序流之间进行切换.串行流就不必再细说了,并行流主要是为了为了适应目前多核机器的时代,提高系统CP

基于Java8 Stream API实现数据抽取收集

目标&背景 我们以"处理订单数据"为例,假设我们的应用是一个分布式应用,有"订单应用","物流应用","商品应用"等都是独立的服务.本次我们的目的需要展示订单列表完整数据: 1.查询订单列表. 2.批量查询物流信息. 3.将物流信息填充到订单主信息中. 假设我们定义了一个订单类,具有几个关键的属性:订单号,状态,订单价,快递信息.如下所示: class Order{ String orderSeq; String st

java8使用Stream API方法总结

Stream是java8中处理集合的关键抽象概念,它可以指定您希望对集合进行的操作,可以执行非常复杂的查找.过滤和映射数据等操作.使用Stream API对集合数据进行操作,就类似于使用SQL执行的数据库查询. Stream 的三个操作步骤 1.创建Stream. 得到Stream流的第一种方式: 可以通过Collection系列集合提供提供的Stream()或parallelStream @Test public void test1() { //可以通过Collection系列集合提供提供的

Java 8 Stream操作类型及peek示例解析

简介 java 8 stream作为流式操作有两种操作类型,中间操作和终止操作.这两种有什么区别呢? 我们看一个peek的例子: Stream<String> stream = Stream.of("one", "two", "three","four"); stream.peek(System.out::println); 上面的例子中,我们的本意是打印出Stream的值,但实际上没有任何输出. 为什么呢? 中间

java8 stream的分组功能实例介绍

前言 最近,项目开发时遇到一个问题.根据业务要求,前端给后端上送的参数是一个列表(如List list),因此,后端也用了一个列表来接收.然而,等后端拿到数据后,我发现我需要对相同classId的数据进行统一处理.于是,我找到前端妹妹讨论,看她能不能帮忙把相同classId的数据封装成列表传给我.我好将接收参数修改成以下格式(List list): class Dto{ String classId; List<Student> list; } 这时,前端妹妹评估了下改动程度,眼泪汪汪地看着我

Java9 Stream Collectors新增功能(小结)

Java 9 Stream Collectors新增功能 Java 8 引入Collectors,用于累加输入元素至可变的容器如,Map.List以及Set.本文看看Java 9 新增的两个Collectors:Collectors.filtering 和 Collectors.flatMapping,主要用于和 Collectors.groupingBy 一起提供智能的元素集合. Collectors.filtering方法 Collectors.filtering方法类似于Stream fi

java8中Stream的使用示例教程

前言 Java8中提供了Stream对集合操作作出了极大的简化,学习了Stream之后,我们以后不用使用for循环就能对集合作出很好的操作. 本文将给大家详细介绍关于java8 Stream使用的相关内容,下面话不多说了,来一起看看详细的介绍吧 1. 原理 Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator. 原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作: 高级版本的 Stream,用户只要给出需

Java8中Stream使用的一个注意事项

Stream简介 我们先来看看Java里面是怎么定义Stream的: A sequence of elements supporting sequential and parallel aggregate operations. 我们来解读一下上面的那句话: Stream是元素的集合,这点让Stream看起来用些类似Iterator: 可以支持顺序和并行的对原Stream进行汇聚的操作: 大家可以把Stream当成一个高级版本的Iterator.原始版本的Iterator,用户只能一个一个的遍历

Java 8 Stream 的终极技巧——Collectors 功能与操作方法详解

本文实例讲述了Java 8 Stream 的终极技巧--Collectors 功能与操作方法.分享给大家供大家参考,具体如下: 1. 前言 昨天在 Collection移除元素操作 相关的文章中提到了 Collectors .相信很多同学对这个比较感兴趣,那我们今天就来研究一下 Collectors . 2. Collectors 的作用 Collectors 是 Java 8 加入的操作类,位于 java.util.stream 包下.它会根据不同的策略将元素收集归纳起来,比如最简单常用的是将

Java 8 Stream Api 中的 map和 flatMap 操作方法

1.前言 Java 8提供了非常好用的 Stream API ,可以很方便的操作集合.今天我们来探讨两个 Stream中间操作 map(Function<? super T, ? extends R> mapper) 和 flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) 2. map 操作 map 操作是将流中的元素进行再次加工形成一个新流.这在开发中很有用.比如我们有一个学生集合,我们

详解Java8 Collect收集Stream的方法

Collection, Collections, collect, Collector, Collectos Collection是Java集合的祖先接口. Collections是java.util包下的一个工具类,内涵各种处理集合的静态方法. java.util.stream.Stream#collect(java.util.stream.Collector<? super T,A,R>)是Stream的一个函数,负责收集流. java.util.stream.Collector 是一个收

详解java8中的Stream数据流

Stream是java8引入的一个重度使用lambda表达式的API.Stream使用一种类似用SQL语句从数据库查询数据的直观方式来提供一种对Java集合运算和表达的高阶抽象.直观意味着开发者在写代码时只需关注他们想要的结果是什么而无需关注实现结果的具体方式.这一章节中,我们将介绍为什么我们需要一种新的数据处理API.Collection和Stream的不同之处以及如何将StreamAPI应用到我们的编码中. 筛选重复的元素 Stream 接口支持 distinct 的方法, 它会返回一个元素

详解Java8新特性Stream之list转map及问题解决

List集合转Map,用到的是Stream中Collectors的toMap方法:Collectors.toMap 具体用法实例如下: //声明一个List集合 List<Person> list = new ArrayList(); list.add(new Person("1001", "小A")); list.add(new Person("1002", "小B")); list.add(new Person

详解java.lang.reflect.Modifier.isInterface()方法

详解java.lang.reflect.Modifier.isInterface()方法 java.lang.reflect.Modifier.isInterface(int mod)方法判断如果给定mod参数包含final修饰符,则返回true,否则返回false. 声明 以下是java.lang.reflect.Modifier.isInterface()方法的声明. public static boolean isInterface(int mod) 参数 mod - 一组修饰符. 返回值

详解Kotlin中的变量和方法

详解Kotlin中的变量和方法 变量 Kotlin 有两个关键字定义变量:var 和 val, 变量的类型在后面. var 定义的是可变变量,变量可以被重复赋值.val 定义的是只读变量,相当于java的final变量. 变量的类型,如果可以根据赋值推测,可以省略. var name: String = "jason" name = "jame" val max = 10 常量 Java 定义常量用关键字 static final, Kotlin 没有static,

ThinkPHP函数详解之M方法和R方法

首先给大家介绍ThinkPHP函数详解:M方法 M方法用于实例化一个基础模型类,和D方法的区别在于: 1.不需要自定义模型类,减少IO加载,性能较好: 2.实例化后只能调用基础模型类(默认是Model类)中的方法: 3.可以在实例化的时候指定表前缀.数据库和数据库的连接信息: D方法的强大则体现在你封装的自定义模型类有多强,不过随着新版ThinkPHP框架的基础模型类的功能越来越强大,M方法也比D方法越来越实用了. M方法的调用格式: M('[基础模型名:]模型名','数据表前缀','数据库连接

详解Vue项目引入CreateJS的方法(亲测可用)

1 前 言 1.1 CreateJS介绍 CreateJS是基于HTML5开发的一套模块化的库和工具. 基于这些库,可以非常快捷地开发出基于HTML5的游戏.动画和交互应用. A suite of modular libraries and tools which work together or independently to enable rich interactive content on open web technologies via HTML5. 包含4类工具库 EaselJS

对Django中static(静态)文件详解以及{% static %}标签的使用方法

在一个网页中,不仅仅只有一个html骨架,还需要css样式文件,js执行文件以及一些图片等.因此在DTL中加载静态文件是一个必须要解决的问题.在DTL中,使用static标签来加载静态文件.要使用static标签,首先需要{% load static %}. 加载静态文件的步骤如下: 首先确保django.contrib.staticfiles已经添加到settings.INSTALLED_APPS中. 确保在settings.py中设置了STATIC_URL. 注意: 上面两条都是在创建Dja

详解java8在Collection中新增加的方法removeIf

记得我在以前找工作的经历中,遇到过一个面试官问过我一个很基础的问题.问题是:有一个List中有10个元素,我现在想从中删除3个元素,请问怎么做?我当时也没想,就直接说,List的有自带的remove方法,可以直接使用,他说请详细的说明一下,我说写一个for循环,循环的次数是List的长度,然后在循环里面直接删除掉想要删除的元素就可以了. 当时还想,这么简单的问题也问,面试官说,你回去自己试试就知道了,你看按照你说的那样写会不会报错.然后我就懵了,虽然这是个简单的问题但是日常的编码中,我还真没有注

详解Java生成PDF文档方法

Java8 Stream API 详细使用方法与操作技巧指南

最近项目需要实现PDF下载的功能,由于没有这方面的经验,从网上花了很长时间才找到相关的资料.整理之后,发现有如下几个框架可以实现这个功能. 1. 开源框架支持 iText,生成PDF文档,还支持将XML.Html文件转化为PDF文件: Apache PDFBox,生成.合并PDF文档: docx4j,生成docx.pptx.xlsx文档,支持转换为PDF格式. 比较: iText开源协议为AGPL,而其他两个框架协议均为Apache License v2.0. 使用PDFBox生成PDF就像画图

原文  https://www.zhangshengrong.com/p/4yNqjnLWXA/
正文到此结束
Loading...