java8函数式编程(Lambda表达式,Optional,Stream流)从入门到精通

文章目录

  • 函数式编程
    • Lambda表达式
    • Stream流
      • 创建流
      • 中间操作
      • 终结操作
      • 注意事项
    • Optional
      • 创建对象
        • 消费值
        • 获取值
        • 过滤
        • 判断
        • 数据转换
    • 方法引用
    • 高级用法
      • 基本数据类型优化
      • 并行流

函数式编程

  • 不关心具体的对象,只关心数据参数和 具体操作

Lambda表达式

  • 格式:

    • () -> {}
  • 假如接口只有一个 函数需要被重写,则可以使用 Lambda表达式来 代替 类的创建和重写

  • 省略规则:

    1. 参数类型可以省略
    2. 方法体只有一句代码时大括号return和唯一一句代码的分号可以省略
    3. 方法只有一个参数时小括号可以省略

Stream流

  • 对集合进行操作

创建流

  • 集合对象. stream()

  • 单列集合

    • 数组:

      • 使用 Arrays 数组工具类 来创建

      • 使用 stream.of创建

      • Integer[] arr = {1,2,3,4,5};
        Stream<Integer> stream = Arrays.stream(arr);
        Stream<Integer> stream2 = Stream.of(arr);
        
  • 双列集合:

    • 先转换为 Set<Map.Entry<String, String>>,再获取 Stream

    • Map<String ,String > map = new HashMap<>();
      Set<Map.Entry<String, String>> entries = map.entrySet();
      Stream<Map.Entry<String, String>> stream = entries.stream();
      

中间操作

  • distinct

    • 去重
      • 依靠 Objec.equals方法
        • 不重写是 地址相同
  • filter(条件)

    • 条件过滤

      • list.stream()
                .distinct() //过滤重复元素
                .filter(s -> s.length() <=3)
                .forEach(s -> System.out.println(s));
        
  • map

    • 转化集合中每个元素的类型:

      • List<String > list = new ArrayList<>();
        list.add("111");
        list.add("111");
        list.add("2222");
        // forEach
        //过滤条件
        list.stream()
                .map(s -> Integer.valueOf(s))
                .forEach(integer -> System.out.println(integer));
        
  • sorted 排序

    • 先将流中类型 转换为 Comparable

    • 如果是空参,自定义类型需要实现Comparable接口

      • List<String > list = new ArrayList<>();
        list.add("111");
        list.add("333");
        list.add("2222");
        // forEach
        //过滤条件
        list.stream()
                .sorted()
                .forEach(integer -> System.out.println(integer));
        
    • 还可以传入参数

      • list.stream()
                .map(s -> Integer.valueOf(s))
                .sorted(new Comparator<Integer>() {
                    @Override
                    public int compare(Integer o1, Integer o2) {
                        return o1-o2;
                    }
                })
                .forEach(integer -> System.out.println(integer));
        
  • limit:

    • 设置流的最大长度

      • list.stream()
                .limit(2)
                .forEach(System.out::println);
        
  • skip:

    • 跳过前n个元素

      • list.stream()
                .skip(2)
                .forEach(System.out::println);
        
  • flatMap

    • 将流中一个元素 转换成 流元素

      • List<List<String >> list = new ArrayList<>();
        list.add(Arrays.asList("111","2222"));
        list.add(Arrays.asList("1121","2222"));
        list.add(Arrays.asList("113","2222"));
        // forEach
        //过滤条件
        list.stream()
                .flatMap(strings -> strings.stream())
                .forEach(System.out::println);
        
        • 输出:

          • image-20231113143845889
        • 未简化:

          • //过滤条件
            list.stream()
                    .flatMap(new Function<List<String>, Stream<?>>() {
                        @Override
                        public Stream<?> apply(List<String> strings) {
                            return strings.stream();
                        }
                    })
                    .forEach(System.out::println);
            

终结操作

  • forEach

    • 对流中元素进行遍历操作
  • count:

    • 获取流中元素的 个数

      • long count = list.stream()
                .flatMap(strings -> strings.stream())
                .count();
        System.out.println(count);
        
  • min & max

    • 求流中最值

      • 重写比较方法:

        • Optional<Integer> count = list.stream()
                  .flatMap(strings -> strings.stream())
                  .map(s -> Integer.valueOf(s))
                  .max(new Comparator<Integer>() {
                      @Override
                      public int compare(Integer o1, Integer o2) {
                          return o1 - o2;
                      }
                  });
          System.out.println(count);
          
          • 简化:

            • Optional<Integer> count = list.stream()
                      .flatMap(strings -> strings.stream())
                      .map(s -> Integer.valueOf(s))
                      .max((o1, o2) -> o1 - o2);
              System.out.println(count);
              
  • collect:

    • 转换为list,使用 集合类中的 tolist方法:

      • List<List<String >> list = new ArrayList<>();
        list.add(Arrays.asList("111","2222"));
        list.add(Arrays.asList("1121","2222"));
        list.add(Arrays.asList("113","2222"));
        List<String> collect = list.stream()
                .flatMap(strings -> strings.stream())
                .collect(Collectors.toList());
        System.out.println(collect);
        
    • 转换为set,一样:

      • Set<String> collect = list.stream()
                .flatMap(strings -> strings.stream())
                .collect(Collectors.toSet());
        System.out.println(collect);
        
    • 转换为 Map集合

      • Map<String, String> collect = list.stream()
                .flatMap(strings -> strings.stream())
                .distinct()
                .collect(Collectors.toMap(s -> s, s -> s));
        System.out.println(collect);
        
  • 查找:

    • anyMatch

      • 任意一个满足就为 true

        • boolean b = list.stream()
                  .flatMap(strings -> strings.stream())
                  .anyMatch(s -> s.length() > 10);
          
    • allMatch

      • 所有满足才为true
    • noneMatch

      • 都不满足才为 true
  • 匹配:

    • findAny

      • 获取任意一个满足条件的 元素
    • findFirst

      • 获取第一个元素

        • List<List<String >> list = new ArrayList<>();
          list.add(Arrays.asList("111","2222"));
          list.add(Arrays.asList("1121","2222"));
          list.add(Arrays.asList("113","2222"));
          Optional<String> first = list.stream()
                  .flatMap(strings -> strings.stream())
                  .sorted()
                  .findFirst();
          first.ifPresent(System.out::println);
          
  • reduce归并

    • 对流中数据按照指定的计算方式计算出一个结果

    • 原理:

      • 两个参数的重载形式内部的计算方式如下:

        • image-20231113151352426
      • 一个参数:

        • 把第一个参数 作为 初始化值
        • image-20231113152846836
    • 使用:

      • 0 : 初始值

      • (result, integer2) -> result + integer2 执行的操作

      • List<List<String >> list = new ArrayList<>();
        list.add(Arrays.asList("111","2222"));
        list.add(Arrays.asList("1121","2222"));
        list.add(Arrays.asList("113","2222"));
        Integer reduce = list.stream()
                .flatMap(strings -> strings.stream())
                .map(s -> Integer.valueOf(s))
                .reduce(0, (result, integer2) -> result + integer2);
        

注意事项

  1. 惰性求值
    • 没有终结操作,中间操作不会执行
  2. 流是一次性的
    • 一个流只能执行一次 终结操作
  3. 不会影响原数据

Optional

  • 预防空指针异常

创建对象

  • 使用Optional.ofNullable

    • String s = new String("1");
      Optional<String> s1 = Optional.ofNullable(s);
      s1.ifPresent(s2 -> System.out.println(s2));
      
消费值
  • s1.ifPresent(s2 -> System.out.println(s2));
    
获取值
  • orElseGet

    • 为空则使用重写的 返回值

    • String s = null;
      Optional<String> s1 = Optional.ofNullable(s);
      System.out.println(s1.orElseGet(() -> "222"));
      
  • orElseThrow

    • 为空,则抛出异常
过滤
  • filter

    • 假如不满足过滤条件,则返回 Optional.empty

      • String s = "null";
        Optional<String> s1 = Optional.ofNullable(s);
        Optional<String> s2 = s1.filter(s3 -> s3.length() < 2);
        System.out.println(s2); //打印 Optional.empty
        
判断
  • isPresent
    • 判断是否存在
数据转换
  • 使用map 进行 Optional类型的转换

    • String s = "1";
      Optional<String> s1 = Optional.ofNullable(s);
      Optional<Integer> i = s1.map(s2 -> Integer.valueOf(s2));
      i.ifPresent(System.out::println); //1
      

方法引用

  • 在使用 Lambda 表达式的时候,如果方法体中只有一个方法 的调用话,就可以使用 类名或者对象名::方法名 来简化

高级用法

基本数据类型优化

  • 我们之前用到的很多Stream的方法由于都使用了泛型。

  • 所以涉及到的参数和返回值都是引用数据类型。

  • 即使我们操作的是整数小数,但是实际用的都是他们的包装类

  • JDK5中引入的自动装箱和自动拆箱让我们在使用对应的包装类时就好像使用基本数据类型一样方便。

  • 但是你一定要知道装箱和拆箱肯定是要消耗时间的。

  • 虽然这个时间消耗很下。但是在大量的数据不断的重复装箱拆箱的时候,你就不能无视这个时间损耗了。

  • 所以为了让我们能够对这部分的时间消耗进行优化。

  • Stream还提供了很多专门针对基本数据类型的方法。

  • 例如: mapToInt,mapToLong,mapToDouble,flatMapTolnt,flatMapToDouble等。

    • List<List<String >> list = new ArrayList<>();
      list.add(Arrays.asList("111","2222"));
      list.add(Arrays.asList("1121","2222"));
      list.add(Arrays.asList("113","2222"));
      list.stream()
              .flatMap(strings -> strings.stream())
              .mapToInt(s -> Integer.valueOf(s))
              .forEach(System.out::println);
      

并行流

  • 当流中有大量元素时,我们可以使用并行流去提高操作的效率。其实并行流就是把任务分配给多个线程去完全。

  • 如果我们自己去用代码实现的话其实会非常的复杂,并且要求你对并发编程有足够的理解和认识。

  • 而如果我们使用Stream的话,我们只需要修改一个方法的调用就可以使用并行流来帮我们实现,从而提高效率。

  • 使用parallel()

    • peek中间操作

    • List<List<String >> list = new ArrayList<>();
      list.add(Arrays.asList("111","2222"));
      list.add(Arrays.asList("1121","2222"));
      list.add(Arrays.asList("113","2222"));
      OptionalInt first = list.stream()
          .parallel()
          .flatMap(strings -> strings.stream())
          .mapToInt(s -> Integer.valueOf(s))
          .peek(i -> System.out.println(i + ":" + Thread.currentThread().getName()))
          .findFirst();
      
      • 打印:
        • image-20231113163806329

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/140958.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Oracle用户密码修改为永不过期

1、查询密码有效时长 select * from dba_profiles where profileDEFAULT and resource_namePASSWORD_LIFE_TIME;没有修改的话 LIMIT 是 180 2、查看用户密码过期时间 select username,account_status,expiry_date,profile from dba_users;3、修改密码为永不过期 alter prof…

Flink SQL -- 反压

1、测试反压&#xff1a; 1、反压&#xff1a; 指的是下游消费数据的速度比上游产生数据的速度要小时会出现反压&#xff0c;下游导致上游的Task反压。 2、测试反压&#xff1a;使用的是DataGen CREATE TABLE words (word STRING ) WITH (connector datagen,rows-per-second…

SPSS时间序列分析:序列图

前言&#xff1a; 本专栏参考教材为《SPSS22.0从入门到精通》&#xff0c;由于软件版本原因&#xff0c;部分内容有所改变&#xff0c;为适应软件版本的变化&#xff0c;特此创作此专栏便于大家学习。本专栏使用软件为&#xff1a;SPSS25.0 本专栏所有的数据文件请点击此链接下…

智能设备管理软件有什么用?如何让工厂设备维修管理更高效?

在当今这个数字化、智能化的时代&#xff0c;企业的生存与发展离不开高效、有序的管理。特别是在制造业中&#xff0c;设备报修与维修管理是关系到企业生产效益、安全和持续发展的关键环节。今天&#xff0c;我们就来聊聊如何通过智能化的设备管理软件&#xff0c;让工厂设备的…

高版本模拟器安装burp证书

一、下载burp证书&#xff0c;安装openssl http://burp自己找官网安装opensslWin32/Win64 OpenSSL Installer for Windows - Shining Light Productions (slproweb.com)二、查看模拟器端口并连接 adb devices openssl x509 -inform der -in cacert.der -out burp.pem openssl…

AI工具-PPT-SlidesAI

SlidesAI 使用手册 https://tella.video/get-started-with-slidesai-tutorial-18yq 简介 SlidesAI 是一款快速创建演示文稿的AI工具&#xff0c;适用于无设计经验的用户。 开始使用 1. **安装与设置** - 访问 [SlidesAI官网](https://www.slidesai.io/zh)。 - 完成简单的设置…

Java事务详解

一、事务的理解&#xff1a; 1、事务的特性&#xff1a; 1) 原子性&#xff08;atomicity&#xff09;&#xff1a;事务是数据库的逻辑工作单位&#xff0c;而且是必须是原子工作单位&#xff0c;对于其数据修改&#xff0c;要么全部执行&#xff0c;要么全部不执行。 2) 一致性…

不同优化器的应用

简单用用&#xff0c;优化器具体参考 深度学习中的优化器原理(SGD,SGDMomentum,Adagrad,RMSProp,Adam)_哔哩哔哩_bilibili 收藏版&#xff5c;史上最全机器学习优化器Optimizer汇总 - 知乎 (zhihu.com) import numpy as np import matplotlib.pyplot as plt import torch # …

注意力机制(Attention)、自注意力机制(Self Attention)和多头注意力(Multi-head Self Attention)机制详解

目录 参考一、Attention注意力机制原理计算过程 二、自注意力机制2.1 自注意力关键&#xff01;&#xff01;2.2 实现步骤1. 获取 K Q V2. MatMul3. scale softmax归一化4. MalMul 2.3 自注意力机制的缺陷 三、多头自注意力机制3.1 简介3.2 实现步骤3.3 公式 参考 感谢我的互…

介绍 Docker 的基本概念和优势,以及在应用程序开发中的实际应用

Docker是一种基于容器的虚拟化技术&#xff0c;它允许开发者将应用程序及其依赖项打包到一个轻量级容器中&#xff0c;然后在任何可用的开发、测试和生产环境中进行部署和运行。 下面是Docker的基本概念和优势&#xff1a; 容器&#xff1a;Docker容器是一种独立运行的软件包&a…

【QT】飞机大战

0 项目简介 飞机大战是我们大家所熟知的一款小游戏&#xff0c;本教程就是教大家如何制作一款自己的飞机大战 首先我们看一下效果图 玩家控制一架小飞机&#xff0c;然后自动发射子弹&#xff0c;如果子弹打到了飞下来的敌机&#xff0c;则射杀敌机&#xff0c;并且有爆炸的特…

C语言--假设共有鸡、兔30只,脚90只,求鸡、兔各有多少只​

一.题目描述 假设共有鸡、兔30只&#xff0c;脚90只&#xff0c;求鸡、兔各有多少只&#xff1f; 二.思路分析 本题是一个典型的穷举法例题&#xff0c;而穷举法&#xff0c;最重要的就是条件判断。⭐⭐ 本题中的条件很容易发现&#xff1a; 假设鸡有x只&#xff0c;兔有y只…

基于php+thinphp+vue的教材管理系统

运行环境 开发语言&#xff1a;PHP 数据库:MYSQL数据库 应用服务:apache服务器 使用框架:ThinkPHPvue 开发工具:VScode/Dreamweaver/PhpStorm等均可 项目简介 教材管理系统&#xff0c;主要的模块包括首页、个人中心、学生管理、老师管理、教材征订管理、教师教材退订管理、…

电源基础元件

文章目录 电源基础元件理想电压源理想电流源受控电源 电源基础元件 理想电压源 定义 其两端电压总能保持定值或一定的时间函数&#xff0c;其值与流过它的电流i无关的元件叫理想电压源 理想电压源的电压、电流关系 1.电源两端电压由电源本身决定&#xff0c;与外电路无关&…

【兔子王赠书第7期】机器学习与人工智能实战:基于业务场景的工程应用

文章目录 写在前面机器学习推荐图书写给读者前言本书面向的读者我为什么要写这本书运行本书的示例代码本书导航本书采用的约定使用代码示例 推荐理由粉丝福利写在后面 写在前面 新的一周开始啦&#xff0c;本周博主给大家带来《机器学习与人工智能实战&#xff1a;基于业务场景…

五分钟利用Vite创建Vue项目

1.准备工具 Vite是尤雨溪团队开发的&#xff0c;官方称是下一代新型前端构建工具&#xff0c;能够显著提升前端开发体验。 上面称是下一代&#xff0c;当前一代当然是我们熟悉的webpack Vite 优势 开发环境中&#xff0c;无需打包操作&#xff0c;可快速的冷启动。轻量快速…

初始MySQL(五)(自我复制数据,合并查询,外连接,MySQL约束:主键,not null,unique,foreign key)

目录 表复制 自我复制数据(蠕虫复制) 合并查询 union all(不会去重) union(会自动去重) MySQL表的外连接 左连接 右连接 MySQL的约束 主键 not null unique(唯一) foreign key(外键) 表复制 自我复制数据(蠕虫复制) #为了对某个sql语句进行效率测试,我们需要海量…

【GEE学习日记】GEE下载ERA5指定小时数据

1 背景 ERA5数据集提供了逐小时的气象产品&#xff0c;最近做实验需要用到指定日期的14点的气象数据&#xff0c;所以学习了一下。 我的目的&#xff1a;获取2003年每月5&#xff0c;15&#xff0c;25日 14点的空气温度 2 代码 var roi table.geometry(); // table是我上传…

【计算机网络】VRRP协议理论和配置

目录 1、VRRP虚拟路由器冗余协议 1.1、协议作用 1.2、名词解释 1.3、简介 1.4、工作原理 1.5、应用实例 2、 VRRP配置 2.1、配置命令 2.2、拓扑与配置&#xff1a; 1、VRRP虚拟路由器冗余协议 1.1、协议作用 虚拟路由冗余协议(Virtual Router Redundancy Protocol&am…

11.13 牛客刷题8/10

11.13 信号完整性 指针地址 的加减&#xff0c;注意 最后转为16进制