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>() {@Overridepublic 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<?>>() {@Overridepublic 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>() {@Overridepublic 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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习(生成式模型)——Classifier Guidance Diffusion

文章目录 前言问题建模条件扩散模型的前向过程条件扩散模型的反向过程条件扩散模型的训练目标 前言 几乎所有的生成式模型&#xff0c;发展到后期都需要引入"控制"的概念&#xff0c;可控制的生成式模型才能更好应用于实际场景。本文将总结《Diffusion Models Beat …

【TiDB】TiDB CLuster部署

目录 0 大纲 一 集群部署工具TiUP简介 1 TiUP 简介 2 TiUP使用 3 TiUP使用举例 二 TiDB Cluster安装配置需求 1 生产环境硬件需求 2 操作系统需求 三 TIDB部署 1 软硬件需求以及前置检查​编辑 2 安装TiUP 组件 ​3 集群拓扑文件 4 执行部署命令 &#xff08;1&…

视频号小店怎么做?运营四步骤,快来学习!

大家好&#xff0c;我是电商糖果 2023年因为视频号小店的爆火&#xff0c;想尝试开店的朋友也不少。 但是因为自己是新手小白&#xff0c;对做电商方面了解的也并不多&#xff0c;再加上它是一个才出来一年多的电商平台。对它的很多规则和玩法并不清楚。 所以&#xff0c;这…

竞赛选题 深度学习的口罩佩戴检测 - opencv 卷积神经网络 机器视觉 深度学习

文章目录 0 简介1 课题背景&#x1f6a9; 2 口罩佩戴算法实现2.1 YOLO 模型概览2.2 YOLOv32.3 YOLO 口罩佩戴检测实现数据集 2.4 实现代码2.5 检测效果 3 口罩佩戴检测算法评价指标3.1 准确率&#xff08;Accuracy&#xff09;3.2 精确率(Precision)和召回率(Recall)3.3 平均精…

Makefile的简单语法学习

通配符 假如一个目标文件所依赖的依赖文件很多&#xff0c;那样岂不是我们要写很多规则&#xff0c;这显然是不合乎常理的&#xff0c;我们可以使用通配符&#xff0c;来解决这些问题。 我们对上节程序进行修改&#xff0c;代码如下&#xff1a; test : a.o b.ogcc -o test $…

【原创】java+swing+mysql办公用品管理系统设计与实现

摘要&#xff1a; 办公用品管理系统是一个设计和实现办公用品库存和使用管理的信息系统。此系统可以提高办公用品的利用率&#xff0c;减少浪费&#xff0c;使办公用品管理更加高效、规范、便捷。本文主要介绍使用javaswingmysql技术去开发实现一个办公用品管理系统。 功能分…

【JUC】三、集合的线程安全

文章目录 1、ArrayList集合线程安全问题分析2、解决方式一&#xff1a;Vector或synchronizedList( )3、解决方式二&#xff1a;CopyOnWriteArrayList 写时复制4、HashSet集合线程不安全的分析与解决5、HashMap集合线程不安全的分析与解决 1、ArrayList集合线程安全问题分析 对…

削峰填谷:居民小区电动汽车有序充电策略研究

摘 要&#xff1a;针对电动汽车在居民小区无序充电对电网系统产生严重隐患及充电间时过长问题&#xff0c;提出一种采用延迟充电的电动汽车有序充电控制策略&#xff0c;并在分析国内外电动汽车有序充电的研究现状后&#xff0c;设计了居民小区电动汽车有序充电策略的总体框架。…

体验家XMPlus收购NPSMeter,稳固体验管理行业“领头羊”地位

2023年9月30日&#xff0c;体验家XMPlus&#xff08;以下简称“体验家”&#xff09;成功完成了对NPSMeter的收购。此次收购是中国客户体验管理&#xff08;CEM&#xff09;赛道进入快速发展以来的首单收购&#xff0c;标志着体验家在CEM领域的进一步扩张&#xff0c;旨在继续完…

Ribbon 负载均衡原理和策略

目录 一、Ribbon 是什么 二、Ribbon 负载均衡原理 三、Ribbon 负载均衡策略 四、Ribbon的应用场景 一、Ribbon 是什么 Ribbon是一个开源的、基于HTTP和TCP的客户端负载均衡工具&#xff0c;它提供了一个简单的、基于配置的负载均衡策略&#xff0c;可以帮助开发人员更轻松…

UITableView的style是UITableViewStyleGrouped

一般情况下&#xff0c;UITableViewStylePlain和UITableViewStyleGrouped是UITableView常用到的style&#xff0c; 之前都是用到的时候&#xff0c;遇到问题直接用度娘&#xff0c;差不多就够用了&#xff0c;今天在修复UI提出的间隙问题&#xff0c;来回改&#xff0c;总觉得…

晶圆代工产能利用率下降,降价大战一触即发 | 百能云芯

晶圆代工行业正面临产能利用率的重大挑战&#xff0c;据悉&#xff0c;联电、世界先进和力积电等主要代工厂纷纷降低明年首季的报价&#xff0c;幅度高达两位数百分比&#xff0c;项目客户降幅更高达15%至20%&#xff0c;各大晶圆代工厂深陷产能利用率六成保卫战。 晶圆代工降价…

EDA实验----四选一多路选择器设计(QuartusII)

目录 一&#xff0e;实验目的 二&#xff0e;实验仪器设备 三&#xff0e;实验原理&#xff1a; 四&#xff0e;实验要求 五&#xff0e;实验内容及步骤 1.实验内容 2.实验步骤 六&#xff0e;实验报告 七.实验过程 1.创建Verilog文件&#xff0c;写代码 2.波形仿真 …

如何在苹果iOS系统ipa应用中获取当前版本号和Bundle ID

在iOS应用开发过程中&#xff0c;了解如何获取和使用应用的当前版本号、Bundle ID和其他相关信息是至关重要的。无论是在应用内显示这些信息&#xff0c;还是在编写一些版本依赖的逻辑时&#xff0c;掌握这些知识点都将帮助开发者进行更有效的管理和维护。本文将详细介绍如何在…

暖手宝上架亚马逊美国站UL499报告测试标准要求

暖手宝是运用物理及化学原理研制的自动取暖保健用品。该产品以其自动生热&#xff0c;有趣&#xff0c;实用等新颖独特的优势&#xff0c;深受欢迎——暖手宝具有自动取暖&#xff0c;理疗保健等多种功能。只要插上电源等上10分钟左右就能发热&#xff0c;最后一种是通过锂电池…

【华为OD题库-015】报文重排序-Java

题目 对报文进行重传和重排序是常用的可靠性机制&#xff0c;重传缓冲区内有一定数量的子报文&#xff0c;每个子报文在原始报文中的顺序已知&#xff0c;现在需要恢复出原始报文。 输入描述 输入第一行为N,表示子报文的个数&#xff0c;0<N < 1000。 输入第二行为N个子报…

【FISCO BCOS】十九、区块链浏览器部署

目录 一、环境依赖 检查环境 1.检查java 二、拉取安装脚本 获取部署安装包 ​编辑 解压安装包 进入目录 三、修改配置 四、部署服务 五、状态检查 检查前后端进程 1.检查后端server进程 2.检查前端的nginx进程 检查进程端口 六、使用区块链浏览器 1.配置群组…

EDA实验-----3-8译码器设计(QuartusII)

目录 一. 实验目的 二. 实验仪器 三. 实验原理及内容 1.实验原理 2.实验内容 四&#xff0e;实验步骤 五. 实验报告 六. 注意事项 七. 实验过程 1.创建Verilog文件&#xff0c;写代码 ​编辑 2.波形仿真 3.连接电路图 4.烧录操作 一. 实验目的 学会Verilog HDL的…

【Java 进阶篇】Java与JQuery:探秘事件绑定、入口函数与样式控制

在现代的Web开发中&#xff0c;Java和JQuery是两个不可或缺的角色。Java为我们提供了强大的后端支持&#xff0c;而JQuery则是前端开发的得力助手。本篇博客将围绕Java和JQuery&#xff0c;深入探讨事件绑定、入口函数和样式控制&#xff0c;带你进入前端开发的奇妙世界。 Jav…

粉够荣获淘宝联盟区域理事会常务理事,携手共铸淘客新生态

淘宝联盟区域理事会于2021年成立&#xff0c;首届成立成都、广州、武汉&#xff0c;服务近2000个领军淘宝客企业&#xff0c;作为区域生态与官方交流重要枢纽&#xff0c;理事会举办近百场交流分享会&#xff0c;带动淘客跨域跨业态交流成长。 2023年9月7日第二届淘宝联盟理事…