java Lambda表达式的使用心得
作者:知我饭否 发布时间:2023-08-18 05:59:51
Lambda表达式的心得
如题,因为博主也是最近才接触到Lambda表达式的(PS 在这里汗颜一会)。我并不会讲解它的原理,诚然任何一件事物如果理解原理的话,使用它必将更加容易。但博主在学习的时候,大多数时候都是学会怎么用,然后在细究原理。就像你骑自行车之前,难道首先还要研究自行车的原理么?
首先Lambda表达式的最简单应用如下
Lambda表达式法
String lam= "初次相识Lambda";
new Thread(() -> System.out.println(lam)).start();
传统方法
String tradition="传统方法";
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(tradition);
}
}).start();
输出结果
很简洁有没有?省略了好多代码是不是,在这里 你可以发现”,Lambda表达式和在Thread创建一个匿名类的作用是一样。我们可以这样认为Lambda表达式本身代表了一个匿名类。
这就是Lambda最大的作用,当然Lambda表达式只能创建接口interface对象。 创建类是不行的,抽象类也是不行的 ,只要是类都是不行的。
首先,我定义了一个自定义的接口,可以用来测试
@FunctionalInterface
public interface Lam {
//Lambda表达式调用的方法
void bda();
//接口的默认方法
default void test(){
System.out.println("我是默认的方法");
};
//接口的静态方法
static void test1(){
System.out.println("我是静态方法");
}
}
使用Lambda表达式 你首先要知道的
1.Lambda表达式只能是接口 interface的创建(PS从上面的例子可以看出来,Runnable是接口,可以查看源代码),并且这个接口只能包含一个方法(除了default方法和static方法)。在接口中创建default方法和static方法都必须要实现方法体如下图
2.如果你用Lambda表达式来创建类 class,则会出现以下错误 ”Target type of a lambda conversion must be an interface“如果你怕自己的定义的接口不符合Lambda表达式的规范 ,你可以在接口interfaca 上面添加注解@FunctionalInterface
3.Lambda表达式的规范表示格式 (parameters) ->{ statements; }。在某些时刻,你还可以简化这个格式
//接口定义的方法无参数时候,并且你想要执行操作也只有一句代码的时候,Lambda会自动返回一句代码,并且可以不用加{}
Lam lam1=()->System.out.println("无参数");
你可以发现后面的大括号{ }没了,这是因为后面代码如果只有一句的话,是可以省略{ } 的
我们把Lam接口定义的调用方法参数修改一下,多出了一个String类型的形参s
//Lambda表达式调用的方法
void bda(String s);
这时候 我们如果使用Lambda表达式,则可以这样
//接口定义的方法有参数时候,并且你想要执行的操作也只有一句代码的时候
Lam lam1=e->System.out.println(e);//这一句还有简化版本 Lam lam1=System.out::println;
lam1.bda("4556");
你又会发现,前面的()中括号也没了,这是因为当参数只有一个的时候,是可以省略()的。
当然也有你要执行很多代码的时候,那这时候可以这样
//接口定义的方法有参数时候,并且你想要执行的操作有很多句代码的时候
Lam lam1 = (String e) -> {
String a = e + "add";
System.out.println(a);
};
lam1.bda("test+");
输出结果如下
当然你还会问Lambda表达式能不能返回东西呢?这是肯定能的,首先我们再把上面的Lam接口方法修改一下
//Lambda表达式调用的方法
String bda(String s);
让bda方法返回一个String值,这次如果我们用Lambda的话
//接口定义的方法有返回值的时候
Lam lam1=s ->{System.out.println(s);return "我是返回的数据";};
lam1.bda("test1");
System.out.println(lam1.bda("test2"));
运行的结果:
总结 Lambda表达式 就是用来创建一个匿名的接口对象,即 它本身就是一个接口的匿名实例。只不过这个接口 有一些条件限制。
Lambda表达式的技巧
Lambda表达式只能用来简化仅包含一个public方法的接口的创建
规则
1.只能是接口
否则报:Target type of a lambda conversion must be an interface
2.只能有一个public方法
否则报:Multiple non-overriding abstract methods found AInterface
或AInterface is not a functional interface
括号形式
testA((int i, int j) -> {});参数要与接口一致
public class Go {
public static void main(String a[]) {
//正确示范
testA((int i, int j) -> {});
//错误示范:Multiple non-overriding abstract methods found xxx;只能有一个public方法
testB((int i, int j) -> {});
//错误示范:Target type of a lambda conversion must be an interface;只能是接口
testC((int i, int j) -> {});
}
public static void testA(AInterface t) { }
public static void testC(CInterface t) {}
public static void testB(BInterface t) {}
interface AInterface {
void xxx(int i, int j);
}
interface BInterface {
void xxx(int i, int j);
void YYY(int i, int j);
}
abstract class CInterface {
abstract void xxx(int i, int j);
}
}
双冒号表达形式
双冒号后面必须是静态方法
否则报错:Non-static method cannot be referenced from a static context
双冒号后面的方法与接口方法参数一样
方法与接口的权限可以不一样
返回类型:如果接口里面方法是void,双冒号后的方法可以任意返回类型,否则要一致
public class Go {
public static void main(String a[]) {
//之前的写法
testA(new AInterface() {
@Override
public void xxx(int i, int j) {
}
});
//正确,相对与接口里面xxx方这是改成静态和换了个名字
testA(Go::mydog);
//正确,加了返回类型和public换成private,也是ok
testA(Go::mydog2);
//错误:Non-static method cannot be referenced from a static context
testA(Go::mydog3);
//这样写也是ok的。
AInterface aInterface = Go::mydog;
testA(aInterface);
}
public static void testA(AInterface t) {
t.xxx(1, 2);
}
interface AInterface {
void xxx(int i, int j);
}
public static boolean mydog(int i, int j) {
System.out.println("mydog" + i + " & " + j);
return false;
}
private static void mydog2(int i, int j) {
System.out.println("mydo2" + i + " & " + j);
}
public void mydog3(int i, int j) {
System.out.println("mydog3" + i + " & " + j);
}
}
来源:https://blog.csdn.net/a1064072510/article/details/80947286


猜你喜欢
- 一. struts2读取进度原理分析(作为草稿存了好久,刚刚发布出来......)1.在strut2中控制文件上传信息的类是实现MultiP
- 一、前言 做过系统参数设置的同学们,肯定遇到过要提供一系列具有相同特点的选项供用户选择。
- 随着kotlin在Android开发领域越来越火,协程在各个项目中的应用也逐渐变得广泛但是协程到底是什么呢?协程其实是个古老的概念,已经非常
- 单例类保证一个类全局仅有一个实例,并提供一个全局访问点,由于只能生成一个实例,因此我们必须把构造函数设为私有函数以禁止他人创建实例。实现1:
- 本节我们来探讨如何使用Feign构造多参数的请求。笔者以GET以及POST方法的请求为例进行讲解,其他方法(例如DELETE、PUT等)的请
- 概述对List进行分组是日常开发中,经常遇到的,在JDK 8中对List按照某个属性分组的代码,超级简单。package test;impo
- Android中SQLite 使用方法详解现在的主流移动设备像android、iPhone等都使用SQLite作为复杂数据的存储引擎,在我们
- 本文实例讲述了Android编程入门之HelloWorld项目目录结构。分享给大家供大家参考,具体如下:我们介绍了如何搭建Android开发
- 大顶堆每个结点的值都大于或等于其左右孩子结点的值小顶堆每个结点的值都小于或等于其左右孩子结点的值对比图实现代码public class He
- 前言最近公司产品突然有一个类似支付宝蚂蚁森林的功能,大致功能跟支付宝蚂蚁森林相像,在看了一下支付宝蚂蚁森林的效果之后,打算先撸一个控件出来,
- 如下所示:public static void main(String[] args) throws IOException {  
- 本文实例为大家分享了Android自定义加载圈动画展示的具体代码,供大家参考,具体内容如下实现如下效果: 该效果图主要有3个动画: 1.旋转
- 使用@RequestParam注解获取参数创建Hello控制器类package com.controller;import org.spri
- 调取钉钉考勤接口的功能公司需要做一个钉钉考勤的页面,让我去写这个功能。结果却比我想象的要麻烦一些!具体是怎么个麻烦呢下面直入正题首先我们找到
- 前言总是觉得对HashMap很熟悉,但最近连续被问到几个关于它的问题,才发现它其实并不简单。这里对关于它的一些问题做个总结,也希望能够大家一
- 一、前言最近写了个项目,前端还没写,需要部署到服务器给女朋友实现前端,可是不熟悉Linux的我,蹑手蹑脚,真的是每一步都是bug,可谓是步步
- 本文实例为大家分享了android Matrix图片随意放大缩小和拖动的具体代码,供大家参考,具体内容如下step1:新建一个项目DragA
- 在用C#开发Web应用时有个痛点,就是本机用VS开启Web应用调试时外部机器无法访问此Web应用。这里将会介绍如何通过设置允许局域网和外网机
- 一、首先我们先大致了解一下什么是多线程。(书上的解释)程序是一段静态的代码,它是应用软件的蓝本。进程是程序的一次动态执行过程,对
- Java提供一种机制叫做序列化,通过有序的格式或者字节序列持久化java对象,其中包含对象的数据,还有对象的类型,和保存在对象中