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,一经查实,立即删除!

相关文章

软考绩效域启迪论文

请点击↑关注、收藏&#xff0c;本博客免费为你获取精彩知识分享&#xff01;有惊喜哟&#xff01;&#xff01; 论干系人绩效域 XX年X月&#xff0c;我作为项目经理参与了XX省人力资源与社会保障厅事业单位人员信息滚轮系统的建设项目&#xff08;以下简称人社厅&#xff09;…

深度学习(生成式模型)——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&…

[Hive] CTE 通用表达式 WITH关键字

在Hive中&#xff0c;CTE代表的是Common Table Expression&#xff08;通用表达式&#xff09;&#xff0c;这是一种SQL语句结构&#xff0c;使用WITH关键字定义的子句。 文章目录 CTE递归 CTE将多个CTE&#xff08;公共表表达式&#xff09;写在同一个SQL文件中 CTE CTE提供…

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

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

MoSe2 二硒化钼 CAS:12058-18-3 瑞禧分享

MoSe2二硒化钼 纯度:4N 99.99%-99.999% 英文名称:Molybdenum Selenide CAS&#xff1a;12058-18-3 分子式为MoSe2.分子量为253.86 灰色粉末,具有层状性质,具有半导体性质。 技术对接:高温高压真空熔炼,处理后进行热扩散 瓶装,1kg/瓶,外加铝复合薄膜真空包装 用途:科研,…

flutter实现视频播放

使用到的库是lecle_yoyo_player 详细请查看文档 main.dart代码如下&#xff1a; import package:flutter/material.dart; import package:lecle_yoyo_player/lecle_yoyo_player.dart;void main() > runApp(const MyApp());class MyApp extends StatefulWidget {const MyA…

如何实现 promise.map,限制 promise 并发数

实现一个带有并发限制的Promise.map函数&#xff0c;可以使用async/await和Promise的特性来管理并发数。 function promiseMap(array, mapper, concurrencyLimit) {return new Promise((resolve, reject) > {const results [];let currentIndex 0;let activeCount 0;asy…

竞赛选题 深度学习的口罩佩戴检测 - 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 平均精…

Python与ArcGIS系列(七)自动化打印地图

目录 0 简述1 获取可用打印机列表2 打印地图3 导出地图至PDF4 导出地图至图像0 简述 本篇介绍如何利用arcpy实现获取可用打印机列表、打印地图、导出地图至PDF和图像。 1 获取可用打印机列表 通过arcpy提供的ListPrinterNames()函数可以生成可用的打印机列表。 import arcpy.m…

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;旨在继续完…

AcWing第129场周赛 - 5290. 重新分装 - 哈夫曼/贪心

解决这个问题前可以先把这三个问题想清楚 1、为什么可以使用哈夫曼树进行求解&#xff1f; 考虑逆操作 参考题解链接 2、为什么恰好是按照每堆所需要的数量分&#xff1f;针对某一堆&#xff0c;可以先分一部分吗&#xff1f; 首先这里按照每堆所正好含有的数量进行划分&#x…

Ribbon 负载均衡原理和策略

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

Go 命令行框架: 构建强大的命令行工具

引言 在软件开发中&#xff0c;命令行工具扮演着重要的角色。它们可以用于自动化任务、数据处理、系统管理等各种场景。而使用合适的命令行框架&#xff0c;可以帮助我们更轻松地构建和维护命令行工具。本文将介绍 Go 语言中一些流行的命令行框架&#xff0c;并讨论它们的特性…

HDU 1027:Ignatius and the Princess II ← next_permutation()

【题目来源】http://acm.hdu.edu.cn/showproblem.php?pid1027【题目描述】 Now our hero finds the door to the BEelzebub feng5166. He opens the door and finds feng5166 is about to kill our pretty Princess. But now the BEelzebub has to beat our hero first. feng5…

UITableView的style是UITableViewStyleGrouped

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