第四章 函数式编程(Lambda表达式&Stream流)

2023-11-11

一、Lambda表达式

特点:是匿名函数 2是可传递

         匿名函数:需要一个函数,但又不想命名一个函数的场景下使用lambda表达式,使用lambda表达式时函数内容应该简单

         可传递:将lambda表达式传递给其他的函数,它当做参数,lambda作为一种更紧凑的代码风格,使java语言表达能力增强

语法:

Lambda表达式在java语言中引入一个新的语法元素和操作符,这个操作符为“->",该操作符被称为Lambda操作符或箭头操作符,它将Lambda分为两个部分:

         左侧:指定了Lambda表达式所需要的所有参数:

         右侧:指定了Lambda体,即Lambda表达式所要执行的功能。

常见语法格式:

有参:lambda表达式的基本格式为(x1,x2)->{表达式}

           参数类型可以省略,两边的括号不能省略

           如果表达式只有一行,那么表达式两边的花括号可以省略

           如果只有一个参数,参数的括号可以省略

  无参:无参时,参数的括号不能省略,参数类型可以省略

           基本格式为()->{表达式}

示例:

语法格式一:无参,无返回值,Lambda体只需要一条语句:
           Runnable r=() ->System.out.println("hello lambda“);
语法格式二:Lambda需要一个参数:
           Consumer<String> con =(x) ->System.out.println(x);
语法格式三:Lambda只需要一个参数时,参数的小括号可以省略:
           Consumer<String> con=x -> System.out.println(x);
语法格式四:Lambda需要两个参数,并且有返回值:
           Comparator<Integer> com=(x,y) ->{
                System.out.println("函数式接口“);
                return Integer.compare(x,y);
          }
语法格式五:当Lambda体只有一条语句是,return与大括号可以省略:
           Comparator<Integer> com =(x,y)->Integer.compare(x,y);

二、Stream 流使用

Stream创建方法:

Stream stream= Stream.empty();  //创建空的Stream对象:
List<String> list=Arrays.asList(‘a’,’b’,’c’); //通过集合类中的stream或者parallelStream方法创建:
Stream listStream=list.stream();         
Stream paralelListStream=list.parallelStream();
Stream s = Stream.of(“a”,”b”,”c”); //通过Stream的of方法创建:

Stream常用方法:

准备数据

Person p1 = new Person("1","张三","123",18,new BigDecimal(61.5));
Person p2 = new Person("2","李四","123",20,new BigDecimal(81.5));
Person p3 = new Person("3","王五","123",20,new BigDecimal(34.5));
Person p4 = new Person("4","赵六","123",17,new BigDecimal(34.5));
Person p5 = new Person("5","赵六","123",18,new BigDecimal(54.4));

List<Person> list  = new ArrayList<>();
list.add(p1); list.add(p2); list.add(p3); list.add(p4); list.add(p5);
Stream<String> stream = Stream.of("T1", "T2", "T3", "T1", "T4", "5");

两类:中间操作,终端操作 || 惰性求值,及早求值

filter    :对stream中元素进行过滤
distinct  :去重
sorted    :排序
limit     :限制个数:获得前几个
skip      :限制个数:去掉前几个
map       :元素一对一转换
close     :关闭stream   

1. filter :元素过滤:

list.stream().filter(person -> person.getAge() >= 18) .collect(Collectors.toList());

2 distinct 去重:

list.stream().filter(st -> st.contains("T")).distlist.inct()
             .collect(Collectors.toList());

3 sorted 排序:

list.stream().sorted(Comparator.comparing(Person::getAge).reversed())
             .collect(Collectors.toList());

sorted 排序 有null值:

list.stream().sorted(Comparator.comparing(Person::getGrade,Comparator.nullsFirst(BigDecimal::compareTo)).reversed())
             .collect(Collectors.toList());

4.limit :类似sql 里 limit ,返回包含前n个元素的流

list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).limit(3)
             .collect(Collectors.toList());

5.skip:skip操作与limit相反,是跳过前n个元素,排序在2个之后的:

list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).skip(3)
             .collect(Collectors.toList());

6.map() 元素1对1 转换:

List<String> list5 = Stream.of("a","b","C").map(string->string.toUpperCase()).collect(Collectors.toList());
List<String> list6 = list.stream().map(Person::getUsername).collect(Collectors.toList());

终端操作:

reduce     :规约,对数据进行操作,返回一个结果
collect    :根据参数做操作
anyMatch   :只要有一个满足返回true,否则false
allMatch   :全部满足返回true,否则false
noneMatch  :全部不满足返回true,否则false    
forEach    :对所有对象进行迭代处理,无返回值
iterator   :返回Stream中所有对象的迭代器
toArray    :返回元素数组   
count      :元素数量
max       :最大元素
min       :最小元素
findFirst :返回第一个对象
findAny   :返回任意一个对象

reduce()规约:对经过参数化操作后的集合进行进一步的运算,可用对集合实施归约操作

// BigDecimal类型:
BigDecimal big1 = list.stream().map(p -> p.getGrade()).reduce(BigDecimal::add).get();
BigDecimal big2 = list.stream().filter(p->p.getGrade()!=null).map(Person::getGrade).reduce(BigDecimal.ZERO,BigDecimal::add);
// int
int i1  = list.stream().map(p -> p.getAge()).reduce(0,(a,b)->a+b);
int i2  = list.stream().map(Person::getAge).reduce(0,Integer::sum);

collect收集:

// collect(toList())方法由Stream里的值生成一个列表,是一个及早求值操作,可以理解为由Stream向Collection的转换
list.stream().filter(p->p.getAge()>=18).collect(Collectors.toList()); 

list转换为map:

Map<String, Person> collect = list.stream().collect(Collectors.toMap(Person::getId, p -> p));
 //使用Collectors.toMap()时 key 不能重复:
 //解决办法:toMap()重载方法:
Map<String, Person> collect1 = list.stream().collect(Collectors.toMap(Person::getUsername, Function.identity(),(k1,k2)->k2));

分组:Collectors.groupingBy

Map<Integer, List<Person>> collect2 = list.stream().collect(Collectors.groupingBy(Person::getAge));

anyMatch allMatch noneMatch (筛选判断)

Stream.of("1", "2", "3", "4", "5").anyMatch(p -> p.equals("7")); //有一个满足为true
Stream.of("1", "2", "3", "4", "5").allMatch(p -> "6".compareTo(p)>0); //全部满足为true
Stream.of("1", "2", "3", "4", "5").noneMatch(p -> "6".compareTo(p) < 0);//全部不满足为true
String ids = "1,2,3,4,5";
List<Object> listIds = Arrays.asList(ids.split(",")).stream().collect(Collectors.toList());
boolean result = listIds.stream().anyMatch(p -> p.equals("2"));
System.out.println(result);

forEach:

list.stream().filter(p -> p.getAge() > 20).forEach(System.out::println);
list.stream().filter(p -> p.getAge() > 20).forEach(person -> System.out.println(person.getUsername()));

count:

long count = list.stream().count();

toArray:

Object[] objects = list.stream().toArray();

Collectors 说明:Collectors是java.util.stream.Collectors类,提供了对流的操作:分组,排序(支持多字段排序),最大值,最小值,平均值。即数据可以在数据库中完成的操作,在Collectors也可以

Collectors.groupingBy(); //分组
Collectors.toList() //流转换
Collectors.toMap()

 

三、方法引用

方法引用用来替换函数式接口,使用方法引用可以是代码更加简洁

使用条件:方法的参数和返回值类型与函数式接口中抽象方法的参数和返回值类型一致

        使用方法:方法引用主要有如下三种使用情况:

                         类::实例方法

                         类::静态方法

                         对象::实例方法

                         其中后两种情况等同于提供方法参数的lambda表达式

例如:System.out::println等同于(x) ->System.out.println(x) Math::pow 等同于(x,y) ->Math.pow(x,y)

第一种,第一个参数会成为执行方法的对象,String::compareToIgncCase等同于(x,y)->x.compareToIgnoreCase(y)

此外,方法引用还可以使用this::methodName及super::methodName表示该对象方法或者父类对象的方法

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

第四章 函数式编程(Lambda表达式&Stream流) 的相关文章

  • 1-1、Qt基本概念以及界面绑定信号与槽的实例

    1 各种程序格式的选择方式 2 例子 新建mainwindow的项目 在ui拖动一个pushbuttton 点击界面下的信号与槽的部分 点击 然后选择发送者 信号 接收者 槽 一下为源码 sampl 1 pro Project create
  • yum提示 “Cannot retrieve metalink for repository: epel/x86_64” 的解决方法

    今天在centos7服务器上用yum的时候发现 yum命令不能用了 不管用yum什么命令都会出现如下提示 完整的错误提示如下 One of the configured repositories failed Unknown and yum
  • 深入理解[观察者模式]原理与技术

    观察者模式 Observer Pattern 也叫做发布 订阅 Publish Subscribe 模式 模型 视图 Model View 模式 这个模式的一个最重要的作用就是解耦 也就是将被观察者和观察者进行解耦 使得他们之间的依赖性更小
  • 【华为OD机试真题 C++】计算最大乘积 【2022 Q4

    前言 华为OD机试真题 C 本专栏包含华为OD机试真题C 解答 会实时更新收纳网友反馈 为大家更新最新的华为德科OD机试试题 为大家提供学习和练手的题库 订阅本专栏后可私信进交流群哦 答案仅供参考 不可照抄哦 题目描述 计算最大乘积 给定一
  • 【Unity3D】粒子光环

    作业要求 参考http i remember fr en 这类网站 使用粒子流编程控制制作一些效果 如 粒子光环 这个网站打不开 参考了一下师兄们的博客的图片 我看了一下 我感觉和上课做的粒子海洋有一些相似 就是需要变成一个环形 制作流程
  • JavaScript 数字去掉小数点后的0

    JavaScript 数字去掉小数点后的0 方法很简单 JavaScript提供了现成的方法 parseFloat function parseNum value value parseFloat value
  • 从头再来系列-Markdown基本语法

    以下内容摘抄于网络 Markdown 简介 Markdown 是一种轻量级标记语言 它允许人们使用易读易写的纯文本格式编写文档 Markdown 语言在 2004 由约翰 格鲁伯 英语 John Gruber 创建 Markdown 编写的
  • oracle基础知识

    1 oracle特点 2 oracle体系 实例 一组oracle后台进程以及在服务器中分配的共享内存区域 数据库 基于磁盘的数据文件 控制文件 日志文件 参数文件和归档文件等组成的物理文件集合 数据库服务器 三者之间的关系 实例用于控制和

随机推荐

  • 【DBeaver日常】查询出结果后,无法回到SQL编辑页面

    正常的查询页面 正常页面可以通过以下图示中的符号进行上下调整 上三角点击完以后的展示页面 如下图 下三角点击完以后的展示页面 如下图 误触以后的页面 误触以后可以通过下图中标示的部分进行恢复 结果面板恢复 最大化区域图示 选择上图中红色框线
  • QT学习之个人编程规范

    每个人对语言的编程习惯都不一样 这里简单介绍一下自己在学习使用Qt时养成的编程习惯 仅供参考 1 命名规则 1 1 常规命名规则 1 1 1 类命名规则 适用对象 1 窗口控件实现类 所有之间或间接继承于QWidget类的实现类 规则 命名
  • OpenMP设置线程数及开启方法

    1 OpenMP线程数设置 通常我们希望并行线程数可以随着机器改变自适应的调整 网上介绍OpenMP的文章很多 但是很少提到该怎么分配线程数 一般来说线程数最大可以开到2 核心数 但是这样电脑计算资源就会被占用的过多 其他程序基本上会卡的不
  • ASP.NET Core WebAPI学习-6

    ASP NET Core WebAPI学习 1 ASP NET Core WebAPI学习 2 ASP NET Core WebAPI学习 3 ASP NET Core WebAPI学习 4 ASP NET Core WebAPI学习 5
  • 数据结构——图的广度优先遍历(BFS)

    本文内图的存储方式是邻接矩阵 不过BFS的具体实现代码与图的存储结构无关 BFS的遍历方法 与树的层次遍历几乎一样 在实现树的层次遍历时 需要找到结点的所有子结点 在实现BFS时 需要找到该结点的所有邻接点 所以在实现BFS之前 需要先学习
  • VS2010 的卸载方法

    如何完全卸载VS2010 亲自体验过 1 首先用360卸载 当卸载完成后 提示有残余的话 就强力清除 PS 笔者使用专用卸载工具 IobitUninstaller 工具 此工具是单文件 免安装 它的特点是拥有360安全卫士 金山安全卫士 Q
  • 复制虚拟机后无法上网的问题

    1 背景 虚拟机用的是VMWare为了得到新的环境 而又不想每次都重装虚拟机 于是某天我复制了一台待机的虚拟机 然鹅它起来后却上不了网 无论我设了静态ip还是动态ip都不行 2 解决方法 问了下chatgpt 说是因为虚拟机的MAC地址冲突
  • 第十五章 AlibabaCloud微服务下的分布式配置中⼼

    1 微服务下的分布式配置中 现在微服务存在的问题 配置 件增多 不好维护 修改配置 件需要重新发布 什么是配置中 句话 统 管理配置 快速切换各个环境的配置 相关产品 百度的disconf 地址 https github com knigh
  • DolphinScheduler跨版本升级1.3.8至3.0.1

    DolphinScheduler跨版本升级1 3 8至3 0 1 Refer 背景 基础环境 依赖版本升级 修改pom xml 问题解决 MYSQL升级 1 文件替换 2 修改表结构 t ds process definition t ds
  • 三菱PLC 红绿灯 步进指令 STL

    自己写的红绿灯 有启动 停止两个按钮 南北通行4S 东西通行5S 链接 https caiyun 139 com m i 0E5CJEoVGt4D0 提取码 kVOA SET 启动 启动标志 RST 启动 停止标志 SET 停止 停止标志
  • 实例讲解MOS管电源开关电路的软启动

    看到一篇文章 作者在做一款大电压 大电流供电的产品 测试发现启动时的冲击电流很大 最大达到了14 2A 见下图示波器通道2的蓝色波形 通道4的绿色波形是采样电阻的电压 当时作者没有经验 不知道如何去解决 后来同事指点说 解决这个问题需要增加
  • C++总结笔记(十)——堆区内存开辟数组和二级指针

    文章目录 一 堆区开辟数组 1 数组指针与指针数组的区别 2 1维数组 3 2维数组 二 二级指针 一 堆区开辟数组 1 数组指针与指针数组的区别 数组指针是指指向数组的指针 它的本体是一个指针 声明指针变量的时候一般用括号 因为括号的优先
  • 解决 invalid user: VMessAEAD is enforced and a non VMessAEAD connection is received.

    2023 01 31 10 27 56 111 181 19 37 45288 rejected common drain common drain unable to drain connection gt EOF gt proxy vm
  • java-实现网页代码的爬取

    爬取一个网页的内容 当然相对路径以及样式都复制不过来 只能复制这个文件的内容 先将所有异常使用Throws抛出的话 import java io BufferedInputStream import java io BufferedOutp
  • ubuntu 安装 nginx

    apt get安装nginx 1 切换到root用户安装 安装最好用root用户安装 不然很多文件权限的报错会让人崩溃 sudo su root apt get install nginx 安装 nginx v 查看安装版本 service
  • 蓝桥杯单片机备考必看内容,学习一周,保底省三!

    这里我先把我弄到的历年考试类型给大家 但是这图只能参考 经历这届蓝桥杯我深有体会 考试当天早上我还在想要不要看看矩阵键盘 但是想着这个考点概率就没去看隔着摆烂 结果真考了按键12 13 16 17的运用 但是有一点要说的是 这届选择题很多历
  • Java获取Process进程ID,并杀掉相应的进程树

    在使用java过程中 很多人可能遇到过这样的问题 当我们通过cmd exe执行命令的时候 如下 Runtime rt Runtime getRuntime Process process rt exec cmd java会在后台进程中开启一
  • 执行yum install时,终端一直刷重复的内容

    执行yum install时 终端一直刷重复的内容 看起来不像报错 可是又无休止的刷 起因 启动nginx报错 说找不到libcrypto so 6 这是因为缺少openssl相关包 于是执行下载 yum install openssl 发
  • 【PTA】 试试手气

    我们知道一个骰子有 6 个面 分别刻了 1 到 6 个点 下面给你 6 个骰子的初始状态 即它们朝上一面的点数 让你一把抓起摇出另一套结果 假设你摇骰子的手段特别精妙 每次摇出的结果都满足以下两个条件 1 每个骰子摇出的点数都跟它之前任何一
  • 第四章 函数式编程(Lambda表达式&Stream流)

    一 Lambda表达式 特点 是匿名函数 2是可传递 匿名函数 需要一个函数 但又不想命名一个函数的场景下使用lambda表达式 使用lambda表达式时函数内容应该简单 可传递 将lambda表达式传递给其他的函数 它当做参数 lambd