java 新特性之 Stream API
强大的 Stream API
一、Stream API 的概述
- Stream到底是什么呢?
是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。
“集合讲的是数据,Stream讲的是计算!”
注意:
- Stream 自己不会存储元素。
- Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
- Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
- Stream 的操作三个步骤
- 创建 Stream
一个数据源(如:集合、数组),获取一个流 - 中间操作
一个中间操作链,对数据源的数据进行处理 - 终止操作(终端操作)
一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用
二、Stream API 的创建
- 创建 Stream方式一:通过集合
Java8 中的 Collection 接口被扩展,提供了两个获取流的方法:
- default Stream< E > stream() : 返回一个顺序流
- default Stream< E > parallelStream() : 返回一个并行流
public class testStream {
@Test
public void test() {
List<String> list = new ArrayList();
list.add("张三");
list.add("李四");
Stream<String> stream = list.stream(); //获取串行流
Stream<String> stream1 = list.parallelStream(); //获取并行流
//终止操作,打印流。
stream.forEach(System.out::println);
stream.forEach(Sustem.out::println);
}
}
- 创建 Stream方式二:通过数组
Java8 中的 Arrays 的静态方法 stream() 可以获取数组流:
- static < T > Stream< T > stream(T[] array): 返回一个流
public class testStream {
@Test
public void test() {
int[] emps = new int[]{1, 2, 3, 4, 5, 6}; //创建数组
IntStream stream = Arrays.stream(emps);
//终止操作,打印流。
stream.forEach(System.out::println);
}
}
- 创建 Stream方式三:通过Stream的of()
可以调用Stream类静态方法 of()方法, 通过显示值创建一个流。它可以接收任意数量的参数。
- public static< T > Stream< T > of(T... values) : 返回一个流
public class testStream {
@Test
public void test() {
Stream<String> stream = Stream.of("a","b","c");
//终止操作,打印流。
stream.forEach(System.out::println);
}
}
- 创建 Stream方式四:创建无限流
可以使用静态方法 Stream.iterate() 和 Stream.generate(), 创建无限流。
- 迭代
public static< T > Stream< T > iterate(final T seed, final UnaryOperator< T > f) - 生成
public static< T > Stream< T > generate(Supplier< T > s)
public class testStream {
@Test
public void test() {
//生成
Stream<Double> stream = Stream.generate(Math::random);
//终止操作,打前 10 个印流。
stream.limit(10).forEach(System.out::println);
//迭代
Stream<Integer> stream1 = Stream.iterate(0,(x) -> x + 2);
//终止操作,打前 10 个印流。
stream1.limit(10).forEach(System.out::println);
}
}
二、Stream API 的中间操作
多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”。
- 筛选与切片
方 法 | 描 述 |
---|---|
filter(Predicate p) | 接收 Lambda , 从流中排除某些元素 |
distinct() | 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素 |
limit(long maxSize) | 截断流,使其元素不超过给定数量 |
skip(long n) | 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补 |
@Test
public void test() {
//迭代,创建无限流
Stream<Integer> stream = Stream.iterate(0,(x) -> x + 2);
//获取大于4的数
Stream<Integer> stream1 = stream.filter((x) -> x > 4);
//获取大于4中的前10个数
Stream<Integer> stream2 = stream1.limit(10);
//舍弃前5个数
Stream<Integer> stream3 = stream2.skip(5);
//终止操作
stream3.forEach(System.out::println);
}
- 映射
方法 | 描述 |
---|---|
map(Function f) | 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。 |
mapToDouble(ToDoubleFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。 |
mapToInt(ToIntFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream。 |
mapToLong(ToLongFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream |
flatMap(Function f) | 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流 |
- 排序
方法 | 描述 |
---|---|
sorted() | 产生一个新流,其中按自然顺序排序 |
sorted(Comparator com) | 产生一个新流,其中按比较器顺序排序 |
Stream API 的终止操作
- 终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void 。
- 流进行了终止操作后,不能再次使用。
- 匹配与查找
方法 | 描述 |
---|---|
allMatch(Predicate p) | 检查是否匹配所有元素 |
anyMatch(Predicate p) | 检查是否至少匹配一个元素 |
noneMatch(Predicate p) | 检查是否没有匹配所有元素 |
findFirst() | 返回第一个元素 |
findAny() | 返回当前流中的任意元素 |
count() | 返回流中元素总数 |
max(Comparator c) | 返回流中最大值 |
min(Comparator c) | 返回流中最小值 |
forEach(Consumer c) | 内部迭代(使用 Collection 接口需要用户去做迭代,称为外部迭代。相反,Stream API 使用内部迭代————它帮你把迭代做了) |
- 归约
方法 | 描述 |
---|---|
reduce(T iden, BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值。返回 T |
reduce(BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值。返回 Optional |
备注: map 和 reduce 的连接通常称为 map-reduce 模式,因 Google
用它来进行网络搜索而出名。
- 收集
方法 | 描述 |
---|---|
collect(Collector c) | 将流转换为其他形式。接收一个 Collector 接口的实现,用于给Stream中元素做汇总的方法 |
Collector 接口中方法的实现决定了如何对流执行收集的操作(如收集到 List、Set、Map)。
另外, Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:
方法 | 返回类型 | 作用 | 调用 |
---|---|---|---|
toList | List | 把流中元素收集到List | List emps= list.stream().collect(Collectors.toList()); |
toSet | Set | 把流中元素收集到Set | Set emps= list.stream().collect(Collectors.toSet()); |
toCollection | Collection | 把流中元素收集到创建的集合 | Collection emps =list.stream().collect(Collectors.toCollection(ArrayList::new)); |
counting | Long | 计算流中元素的个数 | long count = list.stream().collect(Collectors.counting()); |
summingInt | Integer | 对流中元素的整数属性求和 | int |
averagingInt | Double | 计算流中元素Integer属性的平均值 | double avg = list.stream().collect(Collectors.averagingInt(Employee::getSalary)); |
summarizingInt | IntSummaryStatistics | 收集流中Integer属性的统计值。如:平均值 | int SummaryStatisticsiss= list.stream().collect(Collectors.summarizingInt(Employee::getSalary)); |
joining | String | 连接流中每个字符串 | |
String str= list.stream().map(Employee::getName).collect(Collectors.joining()); | |||
maxBy | Optional | 根据比较器选择最大值 | Optionalmax= list.stream().collect(Collectors.maxBy(comparingInt(Employee::getSalary))); |
minBy | Optional | 根据比较器选择最小值 | Optional min = list.stream().collect(Collectors.minBy(comparingInt(Employee::getSalary))); |
reducing | 归约产生的类型 | 从一个作为累加器的初始值开始,利用BinaryOperator与流中元素逐个结合,从而归约成单个值 | int total=list.stream().collect(Collectors.reducing(0, Employee::getSalar,Integer::sum)); |
collectingAndThen | 转换函数返回的类型 | 包裹另一个收集器,对其结果转换函数 | int how= list.stream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size)); |
groupingBy | Map<K, List> | 根据某属性值对流分组,属性为K,结果为V | Map<Emp.Status, List> map=list.stream().collect(Collectors.groupingBy(Employee::getStatus)); |
partitioningBy | Map<Boolean, List> | 根据true或false进行分区 | Map<Boolean,List> vd = list.stream().collect(Collectors.partitioningBy(Employee::getManage)); |
java 新特性之 Stream API的更多相关文章
- Java8 新特性之Stream API
1. Stream 概述 Stream 是Java8中处理集合的关键抽象概念,可以对集合执行非常复杂的查找,过滤和映射数据等操作; 使用 Stream API 对集合数据进行操作,就类似于使用 SQL ...
- Java8 新特性 Lambda & Stream API
目录 Lambda & Stream API 1 Lambda表达式 1.1 为什么要使用lambda表达式 1.2 Lambda表达式语法 1.3 函数式接口 1.3.1 什么是函数式接口? ...
- 【Java8新特性】Stream API有哪些中间操作?看完你也可以吊打面试官!!
写在前面 在上一篇<[Java8新特性]面试官问我:Java8中创建Stream流有哪几种方式?>中,一名读者去面试被面试官暴虐!归根结底,那哥儿们还是对Java8的新特性不是很了解呀!那 ...
- java新特性stream
java新特性stream,也称为流式编程. 在学习stream之前先了解一下java内置的四大函数 第一种函数式函数,后面是lambda表达式写法 /*Function<String,Inte ...
- Java 8 新特性之 Stream 流基础体验
Java 8 新特性之 Stream 流基础体验 package com.company; import java.util.ArrayList; import java.util.List; imp ...
- 乐字节-Java8新特性之Stream流(上)
上一篇文章,小乐给大家介绍了<Java8新特性之方法引用>,下面接下来小乐将会给大家介绍Java8新特性之Stream,称之为流,本篇文章为上半部分. 1.什么是流? Java Se中对于 ...
- Hi java新特性
java新特性 1995.5.23 java语言 1996 jdk1.0 250个类在API 主要用在桌面型应用程序1997 jdk1.1 500 图形用户界面编程1998 jdk1.2 2300 J ...
- 返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 Web API
原文:返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 Web API [索引页][源码下载] 返璞归真 asp.net mvc (10) - asp.net ...
- 乐字节-Java8新特性之Date API
上一篇文章,小乐给大家带来了Java8新特性之Optional,接下来本文将会给大家介绍Java8新特性之Date API 前言: Java 8通过发布新的Date-Time API来进一步加强对日期 ...
随机推荐
- Python带我起飞——入门、进阶、商业实战_ 入门版电子书籍分享,
Python带我起飞--入门.进阶.商业实战_ 免费下载地址 内容简介 · · · · · · <Python带我起飞--入门.进阶.商业实战>针对Python 3.5 以上版本,采用&q ...
- Spring源码 18 IOC refresh方法13
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- RabbitMQ 入门系列:3、基础编码:官方SDK的引用、链接创建、单例改造、发送消息、接收消息。
系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...
- Shell第一章《变量》
shell前言 什么是shell shell-'壳' 命令解释器,一种应用程序 shell语言特点 SHELL语言是指UNIX操作系统的命令语言,同时又是该命令语言的解释程序的简称. Shell本身是 ...
- 详解GaussDB(DWS) 资源监控
摘要:本文主要着重介绍资源池资源监控以及用户资源监控. 本文分享自华为云社区<GaussDB(DWS)资源监控之用户.队列资源监控>,作者: 一只菜菜鸟. GaussDB(DWS)资源监控 ...
- OpenJudge1.5.17
20:球弹跳高度的计算 总时间限制: 1000ms 内存限制: 65536kB 描述 一球从某一高度落下(整数,单位米),每次落地后反跳回原来高度的一半,再落下. 编程计算气球在第10次落地时,共经过 ...
- KingbaseES 如何实现Oracle pipelined 功能
管道函数即是可以返回行集合(可以使嵌套表nested table 或数组 varray)的函数,我们可以像查询物理表一样查询它或者将其赋值给集合变量.KingbaseES 数据库可以用 setof 实 ...
- KingbaseES R6 集群修改data目录
案例说明: 本案例是在部署完成KingbaseES R6集群后,由于业务的需求,集群需要修改data(数据存储)目录的测试.本案例分两种修改方式,第一种是离线修改data目录,即关闭整个集群后,修改数 ...
- 【读书笔记】C#高级编程 第三章 对象和类型
(一)类和结构 类和结构实际上都是创建对象的模板,每个对象都包含数据,并提供了处理和访问数据的方法. 类和结构的区别:内存中的存储方式.访问方式(类是存储在堆上的引用类型,结构是存储在栈的值类型)和它 ...
- Macos下用pycharm运行django项目死活安装不上mysqlclient怎么办!!??
花了我三天时间,佛了 我刚从win过渡到mac,想着把代码迁移一下. 然后看到依赖里面有一个mysqlclient,然后pip3 install死活装不上 解决方案: 在这里写上这个 然后就好,死了