Java Stream 流的使用过程解析

1. 筛选和切片

用谓词筛选

filter方法接受一个返回boolean的方法。

List<Dish> vegetarianMenu=menu.stream().filter(Dish::isVegetarian) .collect(toList());

distinct去重

distinct方法,根据流中元素的hashCode和equals方法。例:

List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream().filter(i -> i % 2 == 0).distinct().forEach(System.out::println);

截短流

limit(n)方法,该方法会返回一个不超过给定长度的流。

如果流是有序的,则最多会返回前n个元素。

limit也可以用在无序流上,比如源是一个Set。这种情况下,limit的结果不会以任何顺序排列。

List<Dish> dishes = menu.stream() .filter(d -> d.getCalories() > 300).limit(3).collect(toList());

跳过元素

skip(n)方法返回一个扔掉了前n个元素的流。如果流中元素不足n个,则返回一个空流。skip方法和limit方法可以看成是相反的操作。

2. 映射

简单映射

流支持map方法,它会接受一个函数作为参数。这个函数会被应用到每个元素上,并将其映射成一个新的元素。

下面的代码,对words中的所有字符串应用String::length方法。

List<String> words = Arrays.asList("Java 8", "Lambdas", "In", "Action");
List<Integer> wordLengths = words.stream().map(String::length).collect(toList());

流的扁平化

什么叫扁平化?举个例子:把Stream<Stream< String >> 变成 Steam< String > 就叫扁平化。

一言以蔽之,flatmap方法让你把一个流中的每个值都换成另一个流,然后把所有的流连接起来成为一个流。

    List<String> words = Arrays.asList("Java 8", "Lambdas", "In", "Action");
    //map函数中每个字符串都被切割为字符串数组,返回一个字符串数组的流
    List<String[]> collect = words.stream()
        .map(word -> word.split(""))
        .distinct()
        .collect(toList());
    //Arrays.stram方法接受一个数组返回一个流
    String[] arrayOfWords = {"Goodbye", "World"};
    Stream<String> streamOfwords = Arrays.stream(arrayOfWords);

    //第一个map返回一个字符串流,流中的元素是一个个的字符串数组。
    //第二个map对每一个字符数组应用Arrays.stream函数,所以每一个字     //符串数组映射为一个字符串流。
    List<Stream<String>> collect1 = words.stream()
        .map(word -> word.split(""))
        .map(v -> Arrays.stream(v))
        .distinct()
        .collect(toList());
    //第一个map返回一个字符串流,流中的元素是一个个的字符串数组。
    //flatMap方法把流中的每个字符串数组都换成一个流,然后连接它们成    //为一个流
    List<String> uniqueCharacters =
        words.stream()
            .map(w -> w.split(""))
            .flatMap(Arrays::stream)
            .distinct()
            .collect(Collectors.toList());

3. 查找和匹配

另一个常见的数据处理套路是看看数据集中的某些元素是否匹配一个给定的属性。Stream API通过allMatch、anyMatch、noneMatch、findFirst、findAny方法提供了这样的工具。

注:这些工具方法的返回值都不是流。所以它们是终端操作

检查谓词是否至少匹配一个元素

if(menu.stream().anyMatch(Dish::isVegetarian)){
 System.out.println("The menu is (somewhat) vegetarian friendly!!");
}

检查谓词是否匹配所有元素

//是否所有元素都匹配
boolean isHealthy = menu.stream().allMatch(d -> d.getCalories() < 1000);
//是否所有元素都 不 匹配
boolean isHealthy = menu.stream().allMatch(d -> d.getCalories() < 1000);

查找元素

findAny方法将返回当前流中的任意元素。

Optional<Dish> dish = menu.stream().filter(Dish::isVegetarian).findAny();

Optional是什么?

查找第一个元素

List<Integer> someNumbers = Arrays.asList(1, 2, 3, 2, 5);
//filter返回一个流,findfirst在该流中找第一个
Optional<Integer> firstSquareDivisibleByThree =
 someNumbers.stream()
 .filter(x -> x == 2)
 .findFirst(); 

4. 归约

归约:将流中的元素相互结合起来,求一个值。比如学生是元素求分数最高的学生、分数是元素求某位同学的总分。

//求numbers中所有数值的集合
int product = numbers.stream().reduce(1, (a, b) -> a * b);

一个初始值,这里是0;

一个BinaryOperator来将两个元素结合起来产生一个新值,这里我们用的是

lambda (a, b) -> a + b。

无初始值

reduce还有一个重载的变体,它不接受初始值,但是会返回一个Optional对象:

Optional sum = numbers.stream().reduce((a, b) -> (a + b));

小结

该篇对于流的使用,做了简要的笔记。可以满足大多数情况的需求。不要只是看看,不要只是做了笔记。这么好用的api,赶紧用起来吧。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java8新特性Stream流实例详解

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

  • Java中的stream流的概念解析及实际运用总结

    流是字节序列的抽象概念. 文件是数据的静态存储形式,而流是指数据传输时的形态. 流类分为两个大类:节点流类和过滤流类(也叫处理流类). 程序用于直接操作目标设备所对应的类叫节点流类,程序也可以通过一个间接流类去调用节点流类,以达到更加灵活方便地读取各种类型的数据,这个间接流类就是过滤流类(也叫处理流类),或者称为包装类. 包装类的调用过程如下图: 流分类的关系 不管流的分类是多么的丰富和复杂,其根源来自于四个基本的类.这个四个类的关系如下: 字节流 字符流 输入流 InputStream Rea

  • Java中FileOutputStream流的write方法

    本文为大家分享了FileOutputStream流的write方法,供大家参考,具体内容如下 /*------------------------ FileOutputStream: ....//输出流,字节流 ....//write(byte[] b)方法: 将b.length个字节从指定字节数组写入此文件输出流中 ....//write(byte[] b, int off, int len)方法:将指定字节数组中从偏移量off开始的len个字节写入此文件输出流 ---------------

  • BufferedInputStream(缓冲输入流)详解_动力节点Java学院整理

    BufferedInputStream 介绍 BufferedInputStream 是缓冲输入流.它继承于FilterInputStream. BufferedInputStream 的作用是为另一个输入流添加一些功能,例如,提供"缓冲功能"以及支持"mark()标记"和"reset()重置方法". BufferedInputStream 本质上是通过一个内部缓冲区数组实现的.例如,在新建某输入流对应的BufferedInputStream后,

  • Java的DataInputStream和DataOutputStream数据输入输出流

    DataInputStream  DataInputStream 是数据输入流.它继承于FilterInputStream. DataInputStream 是用来装饰其它输入流,它"允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型".应用程序可以使用DataOutputStream(数据输出流)写入由DataInputStream(数据输入流)读取的数据. DataInputStream 函数列表: DataInputStream(InputStream in)

  • 简单总结Java IO中stream流的使用方法

    Java语言的输入输出功能是十分强大而灵活的,对于数据的输入和输出操作以"流"(stream)的方式进行.J2SDK提供了各种各样的"流"类,用以获取不同种类的数据,定义在包java.io中.程序中通过标准的方法输入或输出数据. Java中的流可以从不同的角度进行分类: 按照流的方向不同:分为输入流和输出流. 按照处理数据单位的不同:分为字节流(8位)和字符流(16位). 按照功能不同:分为节点流和处理流. 节点流:是可以从一个特定的数据源(节点)读写数据的流(例如

  • 举例讲解Java中的Stream流概念

    1.基本的输入流和输出流 流是 Java 中最重要的基本概念之一.文件读写.网络收发.进程通信,几乎所有需要输入输出的地方,都要用到流. 流是做什么用的呢?就是做输入输出用的.为什么输入输出要用"流"这种方式呢?因为程序输入输出的基本单位是字节,输入就是获取一串字节,输出就是发送一串字节.但是很多情况下,程序不可能接收所有的字节之后再进行处理,而是接收一点处理一点.比方你下载魔兽世界,不可能全部下载到内存里再保存到硬盘上,而是下载一点就保存一点.这时,流这种方式就非常适合. 在 Jav

  • Java Stream 流的使用过程解析

    1. 筛选和切片 用谓词筛选 filter方法接受一个返回boolean的方法. List<Dish> vegetarianMenu=menu.stream().filter(Dish::isVegetarian) .collect(toList()); distinct去重 distinct方法,根据流中元素的hashCode和equals方法.例: List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4); numbe

  • Java输出Hello World完美过程解析

    1. 你会不会输出"Hello World!"? 图1 图 2 当我们学习一门编程语言的时候,我们都会先学如何输出Hello World!

  • java Stream流常见操作方法(反射,类加载器,类加载,反射)

    目录 Stream流常见的中间操作方法 Stream流中常见的终结操作方法 反射 类加载器 反射概述 Stream流常见的中间操作方法 Streamfilter(Predicate predicate):用于对流中的数据进行过滤 predicate接口中的方法 boolean test(T t):对给定的参数进行判断,返回一个布尔值 Stream limit(long maxSize):返回此流中元素组成的流,截取前指定参数个数的数据 Stream skip(long n) :跳过指定参数个数据

  • Java IO流相关知识代码解析

    一.IO流的分类 字符流 Reader InputStreamReader(节点流) BufferedReader(处理流) Writer OutputStreamWriter(节点流) BufferedWriter(处理流) PrintWriter 字节流 InputStream FileInputStream(节点流) BufferedInputStream(处理流) ObjectInputStream(处理流) PrintStream OutputStream FileOutputStre

  • 通过Java读取xml文件内容过程解析

    这篇文章主要介绍了通过Java读取xml文件内容过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 需要下载jar包dom4j:https://dom4j.github.io/ package com.zyb.xml; import java.io.File; import java.util.Iterator; import org.dom4j.Attribute; import org.dom4j.Document; import or

  • java接口私有方法实现过程解析

    这篇文章主要介绍了java接口私有方法实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 问题描述: 我们需要抽取一个共有方法,用来解决两个默认方法之间重复代码的问题 但是这个共有方法不应该让实现类使用,应该是私有化的. 解决方案: 从java 9开始,接口当中允许定义私有方法. 1.普通私有方法,解决多个默认方法之间重复代码问题 格式: private 返回值类型方法名称(参数列表){ 方法体 } 2.静态私有方法,解决多个静态方法之

  • Java super关键字调用父类过程解析

    这篇文章主要介绍了Java super关键字调用父类过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 话不多说,直接上代码: package com.my.pac14; /** * @auther Summerday */ public class SuperTest { public static void main(String[] args) { SubClass sb = new SubClass(20); //创建子类的对象,调

  • Java获取配置文件的值过程解析

    这篇文章主要介绍了java获取配置文件的值过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 java大型项目中都会很多系统常量,比如说数据库的账号和密码,以及各种token值等,都需要统一的管理,如果零落的散布到各个类等具体的代码中的话,在后期管理上将是一场灾难,所有需要对这些变量进行统一的管理,一般都会放到web-service.properties文件中,该文件在项目中的位置如下: web-service.properties文件里的

  • Java使用split截取字符串过程解析

    这篇文章主要介绍了Java使用split截取字符串过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 作用背景:一串字符串中的信息有些是有用的有些是多余的,我们需要把多余的信息去掉 例:"11,22,33,44,55" 这串字符串中我们要取出所有非","的内容 public class test { public static void main(String[] args) { String[] all =

  • Java自定义实现equals()方法过程解析

    这篇文章主要介绍了Java自定义实现equals()方法过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 以常见的自定义Date类型为例,没有经验的朋友可能会觉得直接比较年月日即可,从而写出以下的实现 public class MyDate implements Comparable<MyDate> { private final int year; private final int month; private final int

随机推荐