一文带你掌握Java8强大的StreamAPI

目录
  • Stream 概述
  • Stream 实例化
    • 1、方式一:通过集合
    • 2、方式二:通过数组
    • 3、方式三:通过Stream的of()
    • 4、方式四:创建无限流
  • Stream 中间操作
    • 1、筛选与切片
    • 2、映射
    • 3、排序
  • Stream 终止操作
    • 1、匹配与查找
    • 2、归约
    • 3、收集

Stream 概述

Stream API ( java.util.stream) 把真正的函数式编程风格引入到Java中。这是目前为止对Java类库最好的补充,因为Stream API可以极大提供Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。 使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简言之,Stream API提供了一种高效且易于使用的处理数据的方式。

实际开发中,项目中多数数据源都来自于Mysql,Oracle等。但随着数据源丰富,有MongDB,Radis等,这些NoSQL的数据就需要Java层面去处理。

Stream 和 Collection 集合的区别:Collection 是一种静态的内存数据结构,而Stream 是有关计算的。前者是主要面向内存,存储在内存中,后者主要是面向 CPU,通过 CPU 实现计算。

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

注意:
①Stream 不会存储元素。
②Stream 不会改变源对象。其会返回一个持有结果的新Stream。
③Stream 操作是延迟执行的。其会等到需要结果的时候才执行。

Stream 操作的三个步骤:
①Stream 实例化(创建):一个数据源(如:集合、数组),获取一个流。
②中间操作:一个中间操作链,对数据源的数据进行处理。
③终止操作(终端操作):一旦执行终止操作,就执行中间操作链,并产生结果。之后,不能再被使用(需要的话需要另一个Stream)。

Stream 实例化

1、方式一:通过集合

Java8 中的 Collection 接口被扩展,提供了两个获取流的方法:

import java.util.ArrayList;
import java.util.stream.Stream;

public class StreamAPITest {
    public static void main(String[] args) {
        List<String> arrayList = new ArrayList<>();
        arrayList.add("aa");
        arrayList.add("哈哈");
        arrayList.add("99");
        //返回一个顺序流,即"aa"->"哈哈"->"99"
        Stream<String> stream1 = arrayList.stream();
        //返回一个并行流
        Stream<String> stream2 = arrayList.parallelStream();
    }
}

2、方式二:通过数组

Java8 中的 Arrays 的静态方法 stream() 可以获取数组流:

import java.util.Arrays;
import java.util.stream.Stream;

public class StreamAPITest {
    public static void main(String[] args) {
        Double[] doubles = {1.1, 2.0, 4.3, 9.9};
        Stream<Double> stream = Arrays.stream(doubles);
    }
}

3、方式三:通过Stream的of()

调用Stream类静态方法 of(),通过显示值创建一个流,其可接收任意数量的参数:

import java.util.stream.Stream;

public class StreamAPITest {
    public static void main(String[] args) {
        Double[] doubles = {1.1, 2.0, 4.3, 9.9};
        Stream<Double> doubles1 = Stream.of(doubles);
        Stream<? extends Number> stream = Stream.of(1, 2, 3, 9.9);
    }
}

4、方式四:创建无限流

可以使用静态方法 Stream.iterate() 和 Stream.generate() 创建无限流:

import java.util.stream.Stream;

public class StreamAPITest {
    public static void main(String[] args) {
        // 迭代
        // public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
        Stream<Integer> stream = Stream.iterate(0, x -> x + 2);
        stream.limit(10).forEach(System.out::println);
        // 生成
        // public static<T> Stream<T> generate(Supplier<T> s)
        Stream<Double> stream1 = Stream.generate(Math::random);
        stream1.limit(10).forEach(System.out::println);
    }
}

Stream 中间操作

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

1、筛选与切片

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
 * @Author: Yeman
 * @Date: 2021-10-05-17:25
 * @Description:
 */
public class StreamAPITest {
    public static void main(String[] args) {
        List<String> arrayList = Arrays.asList("aa","bb","cc","aa");
        Stream<String> stream = arrayList.stream();
        stream.filter(e -> !e.equals("aa")).forEach(System.out :: println); //bb cc
        System.out.println("==========");
        arrayList.stream().limit(2).forEach(System.out :: println); //aa bb
        System.out.println("==========");
        arrayList.stream().skip(2).forEach(System.out :: println); //cc aa
        System.out.println("==========");
        arrayList.stream().distinct().forEach(System.out :: println); //aa bb cc
    }
}

2、映射

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
 * @Author: Yeman
 * @Date: 2021-10-05-17:25
 * @Description:
 */
public class StreamAPITest {
    public static void main(String[] args) {
        List<String> arrayList = Arrays.asList("aa","bb","cc","aa");
        Stream<String> stream = arrayList.stream();
        stream.map(x -> x.toUpperCase()).forEach(System.out :: println); //AA BB CC AA
        System.out.println("====================");
        arrayList.stream().map(StreamAPITest::fromStringToStream).forEach(System.out :: println); //类似于add()
        arrayList.stream().flatMap(StreamAPITest::fromStringToStream).forEach(System.out :: println); //类似于addAll()
    }

    public static Stream<Character> fromStringToStream(String str){
        ArrayList<Character> arrayList = new ArrayList<>();
        for (Character c : str.toCharArray()){
            arrayList.add(c);
        }
        return arrayList.stream();
    }
}

3、排序

import java.util.Arrays;
import java.util.List;

/**
 * @Author: Yeman
 * @Date: 2021-10-05-17:25
 * @Description:
 */
public class StreamAPITest {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(2, -9, 0, 22, 6, -1);
        list.stream().sorted().forEach(System.out::println);
        System.out.println("===============");
        list.stream().sorted((e1,e2) -> -Integer.compare(e1,e2)).forEach(System.out :: println);
    }
}

Stream 终止操作

终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void 。流进行了终止操作后,不能再次使用。

1、匹配与查找

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * @Author: Yeman
 * @Date: 2021-10-05-17:25
 * @Description:
 */
public class StreamAPITest {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(2, -9, 0, 22, 6, -1);

        boolean allMatch = list.stream().allMatch(e -> e > 0);
        System.out.println(allMatch);
        boolean anyMatch = list.stream().anyMatch(e -> e > 0);
        System.out.println(anyMatch);
        boolean noneMatch = list.stream().noneMatch(e -> e > 100);
        System.out.println(noneMatch);

        System.out.println("==========================");

        Optional<Integer> first = list.stream().sorted().findFirst();
        System.out.println(first);
        Optional<Integer> any = list.parallelStream().findAny();
        System.out.println(any);

        System.out.println("==========================");

        long count = list.stream().filter(e -> e > 0).count();
        System.out.println(count);

        System.out.println("==========================");

        Optional<Integer> max = list.stream().max(Integer :: compare);
        System.out.println(max);
        Optional<Integer> min = list.stream().min((e1, e2) -> Integer.compare(e1, e2));
        System.out.println(min);

        System.out.println("==========================");
        list.stream().forEach(System.out :: println);
    }
}

2、归约

map 和 reduce 的连接通常称为 map-reduce 模式,因 Google 用它来进行网络搜索而出名。

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * @Author: Yeman
 * @Date: 2021-10-05-17:25
 * @Description:
 */
public class StreamAPITest {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(2, -9, 0, 22, 6, -1);
        Integer reduce1 = list.stream().reduce(0, Integer::sum);
        Integer reduce11 = list.stream().reduce(0, (e1,e2) -> e1 + e2);
        System.out.println(reduce1);
        System.out.println(reduce11);
        Optional<Integer> reduce2 = list.stream().reduce(Integer::sum);
        System.out.println(reduce2);
    }
}

3、收集

Collector 接口中方法的实现决定了如何对流执行收集的操作(如收集到 List、Set、
Map)。另外, Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: Yeman
 * @Date: 2021-10-05-17:25
 * @Description:
 */
public class StreamAPITest {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(2, -9, 0, 22, 6, -1);
        List<Integer> collect = list.stream().filter(e -> e > 0).collect(Collectors.toList());
        collect.forEach(System.out :: println); //2 22 6
    }
}

到此这篇关于一文带你掌握Java8强大的StreamAPI 的文章就介绍到这了,更多相关Java Stream内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java基础:流Stream详解

    目录 写在前面 一."流"概念 二.流的分类 1.按流的方向分为:输入流.输出流 2.按流处理数据的单位分为:字节流.字符流 3.按流的功能分为:节点流(又称低级流).过滤流(又称高级流.处理流.包装流) 4.字节流与字符流区别 三.流的方法 1.字节流 字节输入流类:FileInputStream.BufferedInputStream和DataInputStream 构造方法: 常用方法: 构造方法: 常用方法: 构造方法: 常用方法: 字节输出流类:FileOutputStrea

  • java8如何用Stream查List对象某属性是否有重复

    目录 使用Stream查List对象某属性是否有重复 练习一下stream的一些用法 list的五种去重方式 方法一:使用java8新特性stream进行List去重 方法二:双重for循环去重 方法三:set集合判断去重,不打乱顺序 方法四:遍历后判断赋给另一个list集合 方法五:set和list转换去重 使用Stream查List对象某属性是否有重复 Java8开发中,针对List对象集合,常需要判断某个属性是否存在重复值.用Stream流处理能方便的得到结果. 练习一下stream的一些

  • 关于JAVA8的 Stream学习

    目录 一.Stream的使用 1.1 创建 1.2 步骤 二.Stream的特性 三.中间操作 3.1 filter() 3.2 limit() 3.3 skip() 3.4 map() 3.5 sorted 四.终止操作 4.1 allMatch 4.2anyMatch 4.3noneMatch 4.4 findFirst() 4.5 findAny() 4.6 count 4.7 max 4.8 min 4.9 forEach 4.10 reduce 4.11 collect 一.Strea

  • Java8特性之用Stream流代替For循环操作详解

    目录 准备一个实体类 准备一个List集合 传统的for循环 使用Stream流 先声明筛选条件,在遍历 Stream操作 嵌套循环(2层) 准备一个实体类 public class Student { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int get

  • Java8实战之Stream的延迟计算

    目录 一.函数式编程 1.1 示例一:方法中没有任何操作会修改现有结构 1.2 实例二:"尾-递"迭代 二.科里化 三.函数式数据结构--持久化的 四.Stream的延迟计算 4.1 列表接口 4.2 延迟列表 4.3 创建一个无限延迟的列表 4.4 创建一个无限延迟的质数列表 4.5 使用无限延迟的质数列表 总结 一.函数式编程 要被称为函数式,函数或方法不应该抛出任何异常.使用Optional<R> 类型作为返回值. 透明性:方法中没有任何操作会修改现有结构 使用Jav

  • 一文带你掌握Java8强大的StreamAPI

    目录 Stream 概述 Stream 实例化 1.方式一:通过集合 2.方式二:通过数组 3.方式三:通过Stream的of() 4.方式四:创建无限流 Stream 中间操作 1.筛选与切片 2.映射 3.排序 Stream 终止操作 1.匹配与查找 2.归约 3.收集 Stream 概述 Stream API ( java.util.stream) 把真正的函数式编程风格引入到Java中.这是目前为止对Java类库最好的补充,因为Stream API可以极大提供Java程序员的生产力,让程

  • 一文带你掌握Java8中Lambda表达式 函数式接口及方法构造器数组的引用

    目录 函数式接口概述 函数式接口示例 1.Runnable接口 2.自定义函数式接口 3.作为参数传递 Lambda 表达式 内置函数式接口 Lambda简述 Lambda语法 方法引用 构造器引用 数组引用 函数式接口概述 只包含一个抽象方法的接口,称为函数式接口. 可以通过 Lambda 表达式来创建该接口的对象. 可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口.同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口.

  • 一文带你彻底搞懂Lambda表达式

    1. 为什么使用Lambda表达式 Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升. 我们来看一下使用lambda之前创建匿名内部类: new Thread(new Runnable() { @Override public void run() { System.out.println("执行Runnable方法"); } });

  • 一文带你了解Java中的ForkJoin

    目录 什么是ForkJoin? ForkJoinTask 任务 ForkJoinPool 线程池 工作窃取算法 构造方法 提交方法 创建工人(线程) 例:ForkJoinTask实现归并排序 ForkJoin计算流程 前言: ForkJoin是在Java7中新加入的特性,大家可能对其比较陌生,但是Java8中Stream的并行流parallelStream就是依赖于ForkJoin.在ForkJoin体系中最为关键的就是ForkJoinTask和ForkJoinPool,ForkJoin就是利用

  • 一文带你解密Python可迭代对象的排序问题

    假设有一个可迭代对象,现在想要对它内部的元素进行排序,我们一般会使用内置函数 sorted,举个例子: data = (3, 4, 1, 2, 5) print(     sorted(data) )  # [1, 2, 3, 4, 5] data = (3.14, 2, 1.75) print(     sorted(data) )  # [1.75, 2, 3.14] data = ["satori", "koishi", "marisa"]

  • 一文带你了解Python列表生成式应用的八重境界

    目录 1. 引言 2. Level1: 基础用法 3. Level2: 加入条件语句 4. Level3: 加入 enumerate() 5. Level4: 加入 zip() 6. Level5: 加入三目运算符 7. Level6: 嵌套循环 8. Level7: 嵌套列表生成式 9. Level8: 合并上述所有技巧 10. 应用栗子 11. 总结 1. 引言 在Python中有非常多且好用的技巧,其中使用最多的是列表生成式,往往可以将复杂的逻辑用简单的语言来实现,本文重点介绍列表生成式应

  • 一文带你入门SpringMVC的配置与使用

    目录 1.概述 2.中心控制器 3.搭建SpringMVC 更新pom依赖 配置web.xml 配置springmvc-servlet.xml 创建Controller 创建视图层 1.概述 Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架. Spring MVC的特点: 轻量级,简单易学 高效 , 基于请求响应的MVC框架 与Spring兼容性好,无缝结合 约定优于配置 功能强大:RESTful.数据验证.格式化.本地化.主题等 简洁灵

  • 一文带你了解ChatGPT API的使用

    目录 1.概述 2.内容 2.1 ChatGPT优点 2.2 ChatGPT的应用场景 2.3 ChatGPT的发展前景 3.API应用 4.API代码实现 4.1 Python实现 4.2 JavaScript实现 4.3 Java实现 4.4 智能对话简易实现 5.总结 1.数据准备 2.模型训练 3.对话生成 4.模型评估 1.概述 随着人工智能技术的不断发展,越来越多的AI产品被应用到各个领域,其中最具代表性的莫过于人工智能语言模型.语言模型是一种可以通过学习大量语言数据来预测文本或语音

  • 一文带你了解如何正确使用MyBatisPlus

    目录 1.创建测试表 2.创建 Spring Boot 工程 3.导入依赖 4.编写数据库配置文件 5.编写代码 6.CRUD 测试 7.打印SQL语句 本篇文章,我们通过 MyBatis Plus 来对一张表进行 CRUD 操作,来看看是如何简化我们开发的. 1.创建测试表 创建 USER 表: DROP TABLE IF EXISTS `user`; CREATE TABLE `user` (   `ID` int(11) NOT NULL,   `USER_NAME` varchar(32

  • 一文带你了解 C# DLR 的世界(DLR 探秘)

    在很久之前,我写了一片文章详解C# 匿名对象(匿名类型).var.动态类型 dynamic,可以借鉴.因为那时候是心中想当然的认为只有反射能够在运行时解析对象的成员信息并调用成员方法.后来也是因为其他的事一直都没有回过头来把这一节知识给补上,正所谓亡羊补牢,让我们现在来大致了解一下DLR吧. DLR 全称是 Dynamic Language Runtime(动态语言运行时).这很容易让我们想到同在C#中还有一个叫 CLR 的东西,它叫 Common Language Runtime.那这两者有什

随机推荐