JAVASE进阶:函数式编程——lambda表达式替代匿名内部类

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习
🌌上期文章:JAVASE进阶:强推!源码分析——字符串拼接底层原理、StringBuilder底层原理
📚订阅专栏:JAVASE进阶
希望文章对你们有所帮助

lambda表达式,高级程序员写起来真的是信手拈来,而且他们经常是把lambda放在Collection大类里面的,所以应该要把知识点先学牢。

当要对数组进行逆序排序的时候,可以用匿名内部类,可能会写成:

public class ArrayTest {public static void main(String[] args) {Integer[] arr = {2, 3, 1, 5, 6, 8, 4};Arrays.sort(arr, new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2 - o1;}});System.out.println(Arrays.toString(arr));}
}

这种写法其实并不是太便捷,而lambda就可以便捷我们的写法。在此之前先把匿名内部类知识再简单过一下。

lambda表达式替代匿名内部类

  • 内部类
    • 匿名内部类
  • lambda表达式
    • 函数式编程
    • lambda表达式
    • lambda表达式省略规则
  • lambda表达式练习

内部类

类的五大成员:属性、方法、构造方法、代码块、内部类。
其使用场景其实还是很广泛的,例如现在写一个Javabean类来描述汽车:

public class Car{String name;int carAge;int carColor;String engineName;int engineAge;
}

但是实际上,引擎是独立于车的,不应该成Car这个类的属性。所以应该把engineName和engineAge单独写一个类,但是写在外部,车的引擎自己本身又没有什么作用,所以看起来最完美的是写在Car的内部,表示车里面有发动机,而发送机也是一个独立个体,即:

public class Car{String name;int carAge;int carColor;class Engine{String engineName;int engineAge;}
}

访问特点:内部类可以直接访问外部类成员(包括私有),外部类要访问内部类必须创建对象。

内部类分为4大类:成员内部类、静态内部类、局部内部类以及匿名内部类。其中匿名内部类我们才会经常使用,前面的几个内部类一般我也就是在读源码的时候有见到过,所以暂时没必要理会。

访问的时候,内部类的方法可以用变量调用局部变量,用this.变量调用本内部类的成员变量,用Outer.this.a调用外部类的成员变量。

匿名内部类

匿名内部类本质上就是隐藏了名字的内部类。包含了继承/实现、方法重写、创建对象,格式:

new 类名或接口名(){重写方法;
};

这样的方式可以大大简化我们的代码。可以看下面的例子:

public interface Swim{public abstract void swim();
}

这个方法如果要重写,可以写一个具体的类,例如:

public class Student implements Swim{@Overridepublic void swim(){...}
}

接着在main函数中,需要先创建Student对象,再调用方法。而有了匿名内部类,我们无须Student类就可以重写方法。这个类是没有具体的名字了,但是实际上它还是个类,是类就可以创建对象,要创建这个没有名字的类的对象,可以这么写:

new Swim(){@Overridepublic void swim(){...}
}

注意上面整体是对象,这个对象对应的类没有名字,只是实现了Swim接口。
所以想要调用里面的swim方法时,可以直接写成:

new Swim(){@Overridepublic void swim(){...}
}.swim();

lambda表达式

在最开头写了如何对数组进行逆序的排序,直接调用Arrays里面的sort方法,并把排序规则写成o2-o1就好了,而使用lambda表达式,排序过程可以简化为:

public class ArrayTest {public static void main(String[] args) {Integer[] arr = {2, 3, 1, 5, 6, 8, 4};Arrays.sort(arr, (o1, o2) -> o2 - o1);System.out.println(Arrays.toString(arr));}
}

看起来真的是爽,这其实是一种函数式编程的思想特点。

函数式编程

函数式编程就是一种思想特点,和面向对象是不太一样的。

面向对象是先找到对象,再让对象做事情,匿名内部类写的排序规则就是先创建了Comparator对象,在里面重写了排序的规则,sort函数就调用了这种规则。
这种写法之所以麻烦,是因为sort函数根本不在乎你是哪个对象,它需要的只是重写方法里面的规则,之前就是因为受限于面向对象的原则,所以才写的这么麻烦。

而函数式编程就可以忽略面向对象的复杂语法,强调做什么,而不是谁去做。而lambda表达式其实就是函数式编程思想的体现。

lambda表达式

lambda表达式是JDK8开始后的一种新语法形式,格式:

() -> {}

():方法的形参
->:固定格式
{}:方法的方法体

注意:lambda表达式可以简化匿名内部类的书写,但是不是所有匿名内部类都可以用lambda表达式来简化。
lambda表达式只能简化函数式接口的匿名内部类的写法,其中函数式接口指的是有且仅有一个抽象方法的接口叫做函数式接口,接口上方可以加@FunctionalInterface,如果满足这个要求,则@FunctionalInterface是不会报错的。

lambda作为一个匿名函数,可以把lambda表达式理解成是一段可传递的代码,它可以写出更简洁、更灵活的代码,作为一种更紧凑的代码风格,使Java语言表达能力得到了提升。

lambda表达式省略规则

前面演示lambda表达式,其实是最精简版本的,而朴素版本是这样的:

Arrays.sort(arr, (Integer o1, Integer o2) -> {return o2 - o1;
});

lambda省略规则:

1、参数类型可以不写
2、若只有一个参数,可以直接省略"()"
3、若lambda方法体只有一行,则不用写"{}“、“return”、”;",但是必须同时省略。

lambda表达式练习

很容易的知识点,学了就会做。

对于一个字符串数组,对其长度进行从长到短排序:
1、匿名内部类:

	public static void main(String[] args) {String[] arr = {"a", "aaaa", "aaa", "aa"};Arrays.sort(arr, new Comparator<String>(){@Overridepublic int compare(String o1, String o2) {return o2.length() - o1.length();}});System.out.println(Arrays.toString(arr));}

2、lambda表达式:

	public static void main(String[] args) {String[] arr = {"a", "aaaa", "aaa", "aa"};Arrays.sort(arr, (o1, o2) -> o2.length() - o1.length());System.out.println(Arrays.toString(arr));}

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

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

相关文章

机器学习——集成学习

&#x1f4d5;参考&#xff1a;ysu老师课件西瓜书 期末复习笔记 1.集成学习的基本概念 集成学习&#xff08;ensemble learing&#xff09;通过构建并结合多个学习器来完成学习任务。 有时也被称为多分类器系统&#xff08;multi-classifier system&#xff09;、基于委员会的…

Spring Cloud Stream解密:流式数据在微服务中的魔力

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Spring Cloud Stream解密&#xff1a;流式数据在微服务中的魔力 前言Spring Cloud Stream基础&#xff1a;微服务中的数据流动Binder概念与使用&#xff1a;连接流的音符消息序列化与反序列化&#xf…

开源社区的力量:共同构建数字时代的未来(AI)

开源社区的力量&#xff1a;共同构建数字时代的未来 引言开源社区的定义与发展历程 1. 开源社区的定义2. 发展历程 开源社区的核心价值 1. 技术共享与创新2. 协作与社区建设3. 自由开放的精神 开源社区对数字时代的贡献 1. 技术创新的推动者2. 开放式标准的制定者3. 教育和培训…

【消息队列】kafka整理

kafka整理 整理kafka基本知识供回顾。

Leetcode刷题笔记题解(C++):99. 恢复二叉搜索树

思路&#xff1a; 二叉搜索树的中序遍历是递增序列&#xff0c;可以在中序遍历中记录两个需要交换的节点&#xff0c;直到遍历完毕之后&#xff0c;对两个节点的值进行交换即可得到正确的二叉搜索树 比如中序序列为 1 2 3 7 5 6 4&#xff08;7比5大记录7为x&#xf…

每日OJ题_算法_模拟③_力扣6. Z 字形变换

目录 力扣6. Z 字形变换 解析代码 力扣6. Z 字形变换 6. Z 字形变换 难度 中等 将一个给定字符串 s 根据给定的行数 numRows &#xff0c;以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 "PAYPALISHIRING" 行数为 3 时&#xff0c;排列如下&#xff…

以太网帧格式及ARP协议简介

在以太网中&#xff0c;一个主机和另一个主机进行通信&#xff0c;必须要知道目的主机的MAC地址&#xff08;物理地址&#xff09;&#xff0c;只要知道目的主机的IP地址&#xff0c;就可以通过ARP协议获取目的主机的MAC地址。 1、ARP协议简介 ARP&#xff08;Address Resolut…

处理安装uni-ui依赖一直安装不上

根据官方的文档去安装&#xff0c;我这边把npm换成了pnpm。 搞了一个小时没搞明白为什么下载不下来依赖&#xff0c;原因是镜像的问题。 处理方式&#xff1a;安装了cnpm&#xff0c;去访问国内镜像 安装cnpm&#xff0c;使用国内镜像 npm install -g cnpm --registryhttps…

react 之 useCallback

简单讲述下useCallback的使用方法&#xff0c;useCallback也是用来缓存的&#xff0c;只不过是用于做函数缓存 // useCallbackimport { memo, useCallback, useState } from "react"const Input memo(function Input ({ onChange }) {console.log(子组件重新渲染了…

Ubuntu上开启FTP服务教程

在Ubuntu服务器上配置FTP服务是一个常见的需求&#xff0c;无论是用于文件分享、网站管理还是数据备份。FTP&#xff08;文件传输协议&#xff09;是一种用于在网络上传输文件的协议&#xff0c;它可以让用户通过身份验证下载或上传文件。本文将指导您如何在Ubuntu系统上安装和…

【第二十二课】最短路:多源最短路floyd算法(acwing-852 spfa判断是否存在负环 / acwing-854 / c++代码)

目录 acwing-852 代码如下 一些解释 acwing-854 foyld算法思想 代码如下 一些解释 acwing-852 在spfa求最短路的算法基础上进行修改。 代码如下 #include<iostream> #include<cstring> #include<algorithm> #include<queue> using names…

百分点科技:《数据科学技术: 文本分析和知识图谱》

科技进步带来的便利已经渗透到工作生活的方方面面&#xff0c;ChatGPT的出现更是掀起了新一波的智能化浪潮&#xff0c;推动更多智能应用的涌现。这背后离不开一个朴素的逻辑&#xff0c;即对数据的收集、治理、建模、分析和应用&#xff0c;这便是数据科学所重点研究的对象——…

Python itertools模块:生成迭代器(实例分析)

itertools 模块中主要包含了一些用于生成迭代器的函数。在 Python 的交互式解释器中先导入 itertools 模块&#xff0c;然后输入 [e for e in dir(itertools) if not e.startswith(_)] 命令&#xff0c;即可看到该模块所包含的全部属性和函数&#xff1a; >>> [e for …

6-2 B. DS二叉树--叶子数量

题目描述 计算一颗二叉树包含的叶子结点数量。 提示&#xff1a;叶子是指它的左右孩子为空。 建树方法采用“先序遍历空树用0表示”的方法&#xff0c;即给定一颗二叉树的先序遍历的结果为AB0C00D00&#xff0c;其中空节点用字符‘0’表示。 输入 第一行输入一个整数t&#xff…

【单片机毕业设计6-基于stm32c8t6的智能衣柜系统】

【单片机毕业设计6-基于stm32c8t6的智能衣柜系统】 前言一、功能介绍二、硬件部分三、软件部分总结 前言 &#x1f525;这里是小殷学长&#xff0c;单片机毕业设计篇6基于stm32的智能衣柜系统 &#x1f9ff;创作不易&#xff0c;拒绝白嫖可私 一、功能介绍 -------------------…

C++类与对象的简单应用【日期类的简单实现】

在咱们刚接触C,写一个日期类进行练习&#xff0c;实现从能比较多&#xff0c;如计算日期差&#xff0c;设置日期&#xff0c;输出日期… 下面我会展示一个简单的日期类 声明 #include <iostream> #include <assert.h> using namespace std;class Date { public:b…

Vue 上门取件时间组件

本文使用vue2.0elementui 制作一个上门取件时间组件&#xff0c;类似顺丰&#xff0c;样式如下&#xff1a; 大概功能&#xff1a;点击期望上门时间&#xff0c;下面出现一个弹框可以选择时间&#xff1a; 首先我们定义一些需要的数据&#xff1a; data() {return {isDropdown…

Java 集合List相关面试题

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d7;本文收录于java面试题系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏Rust初阶教程、go语言基…

C++ 动态规划 分组背包问题

有 N 组物品和一个容量是 V 的背包。 每组物品有若干个&#xff0c;同一组内的物品最多只能选一个。 每件物品的体积是 vij &#xff0c;价值是 wij &#xff0c;其中 i 是组号&#xff0c;j 是组内编号。 求解将哪些物品装入背包&#xff0c;可使物品总体积不超过背包容量&a…

2024美赛数学建模ABCDEF题思路代码

--------------------2024美国大学生数学建模竞赛&#xff08;美赛&#xff09;思路&代码---------------------------- 赛题翻译&#xff1a;2024美赛ABCDEF赛题翻译 问题A&#xff08;数据分析题&#xff09;&#xff1a;资源可用性和性别比例&#xff08;MCM&#xff09…