学习Lambda表达式完整篇
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/***
*Lambda表达式
* 一 作用: 只有一个目的就是给函数式接口创建实例对象;
* 什么是函数式接口? 只包含一个抽象方法的接口,包含其他成员一概不管.这个抽象方法可以是自定义的,或者是来自继承树的(父接口)
* 某些情况下Lambda可代替匿名内部类,更加简单.
*二 语法
* 1 形参列表() 只有一个形参的时候可省略括号
* 2 箭头 ->
* 3 代码块 {} 只有一条语句,可省略大括号;且该语句为return语句时可省略return
*
*三 使用场景(Lambda表达式创建的对象属于哪种类型取决于使用场景的类型)
* 比如定义一个函数式接口: interface Shape{ void draw(); default void show(Shape s){}}
* 1 赋值,赋值给函数式变量 Shape shape = ()->{};
* 2 传参,当作方法的实参 Shape.show(()->{});
* 3 强制类型转换中 var shape (Shape)()->{};
*四 java中典型的4类函数式接口(java.util.function)
* 函数式接口( 记忆 判断:生产<--转换-->消费>)
* XxxPredicate boolean test(T t) 判断
* XxxFunction R apply(T t) 转换
* XxxConsumer void accept(T t) 消费
* XxxSupplier T getAsXxx() 生产
*
* 五 注意
* 1 如果对Lambda表达式的形参添加注解,就不能省略形参类型,因为注解必须放发在类型的前面
* (在java11之前,必须声明形参的类型,java11后则可自动推断,但如果给形参添加注解,仍然需要添加形参类型,为方便的使用var就可以了)
* 2 Lambda表达式和匿名内部类一样,当访问局部变量时aa,aa就变成了final变量,不可更改
*
* 六 方法引用和构造器引用: 处于简化代码使用,不是故意如此(Lambda的代码块只有一行代码,该语句是如下情景时)
* 类名::类方法 (当该语句是类名调用类方法时)
* 特定对象::实例方法(当当该语句是一个对象调用它的方法)
* 类名::实例方法(第一个参数作为主调,其他参数作为方法的实参)
* 类名::构造器(当该语句是创建一个对象时)
*
* 七 Lambda表达式和匿名内部类的相同点和区别
* 相同点
* 1 两者内部一样可以访问成员变量,局部变量,且访问局部变量后就会变成final变量
* 2 两者对象都可以调用来自接口的默认方法
* 区别
* 1 匿名内部类可以为任何类(包括抽象类),接口创建对象,而Lambda表达式只能为函数式接口的创建对象,但都必须实现所有的抽象方法
* 2 匿名内部类,终究是一个类,不用把它特殊化,他和普通类实现接口完全一致,所有类,接口继承的特点就是继承一切,除了构造器和代码块),
* 而Lambda与接口的实例,无法访问该类的一切成员,包括default方法
*
*/
//
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@interface NotNull{}
interface AA{
static void doing1(String thing){
System.out.println(thing);
}
default void doing2(String thing){
System.out.println(thing);
}
}
interface BB extends AA{
void doing(String thing);
}
interface IShape extends BB{
// IShape最终继承了AA的draw()抽象方法,因此IShape也是函数式接口
}
interface Rectangle{
void doing(AA aa,String thing);
}
interface Square{
String doing(String thing);
}
public class Lambda表达式 {
public static void main(String[] args) {
//创建一个AA类型的对象,下面要用,别忘记了,aa是怎么来的
AA aa = new AA(){};
System.out.println("------类名::类方法------");
//注解修饰Lambda表达式的形参时必须要加类型,因为注解必须放在类型前面
IShape a1 = (@NotNull var thing)->{
AA.doing1(thing);
};
IShape a2 = AA::doing1;
a1.doing("tom喜欢吃鸡腿");
a2.doing("tom喜欢吃鸡腿");
System.out.println("------实例对象::实例方法------");
IShape b1 = (thing) ->{
aa.doing2(thing);
};
IShape b2 = aa::doing2;
b1.doing("tom喜欢吃鸡腿");
b2.doing("tom喜欢吃鸡腿");
System.out.println("------类名::实例方法------");
Rectangle c1 = (a,thing)->{
aa.doing2(thing);
};
Rectangle c2 = AA::doing2;
c1.doing(aa,"tom喜欢吃鸡腿");
c2.doing(aa,"tom喜欢吃鸡腿");
System.out.println("------类名::构造器------");
Square d1 = (thing)-> new String(thing);
Square d2 = String::new;
String thing1 = d1.doing("tom喜欢吃鸡腿");
String thing2 = d2.doing("tom喜欢吃鸡腿");
System.out.println(thing1);
System.out.println(thing2);
}
}
分类:
JavaSE
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报