强大的 Stream API

一、Stream API 的概述

  1. Stream到底是什么呢?

    是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。

    “集合讲的是数据,Stream讲的是计算!”

注意:

  • Stream 自己不会存储元素。
  • Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
  • Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
  1. Stream 的操作三个步骤
  • 创建 Stream

    一个数据源(如:集合、数组),获取一个流
  • 中间操作

    一个中间操作链,对数据源的数据进行处理
  • 终止操作(终端操作)

    一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用

二、Stream API 的创建

  1. 创建 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);
}
}
  1. 创建 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);
}
}
  1. 创建 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);
}
}
  1. 创建 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 的中间操作

多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”。

  1. 筛选与切片
方 法 描 述
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);
}
  1. 映射
方法 描述
map(Function f) 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
mapToDouble(ToDoubleFunction f) 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。
mapToInt(ToIntFunction f) 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream。
mapToLong(ToLongFunction f) 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream
flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
  1. 排序
方法 描述
sorted() 产生一个新流,其中按自然顺序排序
sorted(Comparator com) 产生一个新流,其中按比较器顺序排序

Stream API 的终止操作

  • 终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void 。
  • 流进行了终止操作后,不能再次使用。
  1. 匹配与查找
方法 描述
allMatch(Predicate p) 检查是否匹配所有元素
anyMatch(Predicate p) 检查是否至少匹配一个元素
noneMatch(Predicate p) 检查是否没有匹配所有元素
findFirst() 返回第一个元素
findAny() 返回当前流中的任意元素
count() 返回流中元素总数
max(Comparator c) 返回流中最大值
min(Comparator c) 返回流中最小值
forEach(Consumer c) 内部迭代(使用 Collection 接口需要用户去做迭代,称为外部迭代。相反,Stream API 使用内部迭代————它帮你把迭代做了)
  1. 归约
方法 描述
reduce(T iden, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 T
reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 Optional

备注: map 和 reduce 的连接通常称为 map-reduce 模式,因 Google

用它来进行网络搜索而出名。

  1. 收集
方法 描述
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的更多相关文章

  1. Java8 新特性之Stream API

    1. Stream 概述 Stream 是Java8中处理集合的关键抽象概念,可以对集合执行非常复杂的查找,过滤和映射数据等操作; 使用 Stream API 对集合数据进行操作,就类似于使用 SQL ...

  2. Java8 新特性 Lambda & Stream API

    目录 Lambda & Stream API 1 Lambda表达式 1.1 为什么要使用lambda表达式 1.2 Lambda表达式语法 1.3 函数式接口 1.3.1 什么是函数式接口? ...

  3. 【Java8新特性】Stream API有哪些中间操作?看完你也可以吊打面试官!!

    写在前面 在上一篇<[Java8新特性]面试官问我:Java8中创建Stream流有哪几种方式?>中,一名读者去面试被面试官暴虐!归根结底,那哥儿们还是对Java8的新特性不是很了解呀!那 ...

  4. java新特性stream

    java新特性stream,也称为流式编程. 在学习stream之前先了解一下java内置的四大函数 第一种函数式函数,后面是lambda表达式写法 /*Function<String,Inte ...

  5. Java 8 新特性之 Stream 流基础体验

    Java 8 新特性之 Stream 流基础体验 package com.company; import java.util.ArrayList; import java.util.List; imp ...

  6. 乐字节-Java8新特性之Stream流(上)

    上一篇文章,小乐给大家介绍了<Java8新特性之方法引用>,下面接下来小乐将会给大家介绍Java8新特性之Stream,称之为流,本篇文章为上半部分. 1.什么是流? Java Se中对于 ...

  7. Hi java新特性

    java新特性 1995.5.23 java语言 1996 jdk1.0 250个类在API 主要用在桌面型应用程序1997 jdk1.1 500 图形用户界面编程1998 jdk1.2 2300 J ...

  8. 返璞归真 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 ...

  9. 乐字节-Java8新特性之Date API

    上一篇文章,小乐给大家带来了Java8新特性之Optional,接下来本文将会给大家介绍Java8新特性之Date API 前言: Java 8通过发布新的Date-Time API来进一步加强对日期 ...

随机推荐

  1. Python带我起飞——入门、进阶、商业实战_ 入门版电子书籍分享,

    Python带我起飞--入门.进阶.商业实战_ 免费下载地址 内容简介 · · · · · · <Python带我起飞--入门.进阶.商业实战>针对Python 3.5 以上版本,采用&q ...

  2. Spring源码 18 IOC refresh方法13

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  3. RabbitMQ 入门系列:3、基础编码:官方SDK的引用、链接创建、单例改造、发送消息、接收消息。

    系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...

  4. Shell第一章《变量》

    shell前言 什么是shell shell-'壳' 命令解释器,一种应用程序 shell语言特点 SHELL语言是指UNIX操作系统的命令语言,同时又是该命令语言的解释程序的简称. Shell本身是 ...

  5. 详解GaussDB(DWS) 资源监控

    摘要:本文主要着重介绍资源池资源监控以及用户资源监控. 本文分享自华为云社区<GaussDB(DWS)资源监控之用户.队列资源监控>,作者: 一只菜菜鸟. GaussDB(DWS)资源监控 ...

  6. OpenJudge1.5.17

    20:球弹跳高度的计算 总时间限制: 1000ms 内存限制: 65536kB 描述 一球从某一高度落下(整数,单位米),每次落地后反跳回原来高度的一半,再落下. 编程计算气球在第10次落地时,共经过 ...

  7. KingbaseES 如何实现Oracle pipelined 功能

    管道函数即是可以返回行集合(可以使嵌套表nested table 或数组 varray)的函数,我们可以像查询物理表一样查询它或者将其赋值给集合变量.KingbaseES 数据库可以用 setof 实 ...

  8. KingbaseES R6 集群修改data目录

    案例说明: 本案例是在部署完成KingbaseES R6集群后,由于业务的需求,集群需要修改data(数据存储)目录的测试.本案例分两种修改方式,第一种是离线修改data目录,即关闭整个集群后,修改数 ...

  9. 【读书笔记】C#高级编程 第三章 对象和类型

    (一)类和结构 类和结构实际上都是创建对象的模板,每个对象都包含数据,并提供了处理和访问数据的方法. 类和结构的区别:内存中的存储方式.访问方式(类是存储在堆上的引用类型,结构是存储在栈的值类型)和它 ...

  10. Macos下用pycharm运行django项目死活安装不上mysqlclient怎么办!!??

    花了我三天时间,佛了 我刚从win过渡到mac,想着把代码迁移一下. 然后看到依赖里面有一个mysqlclient,然后pip3 install死活装不上 解决方案: 在这里写上这个 然后就好,死了