专业编程基础技术教程

网站首页 > 基础教程 正文

Java基础知识 - lambda 表达式

ccvgpt 2024-08-04 12:07:50 基础教程 9 ℃

1、表达式语法

1)lambda 的命名采用的是数学符号 λ;

2)lambda 表达式是一个可传递的代码块,可以用一个函数式接口接收,表示形式如下:

Java基础知识 - lambda 表达式

1、参数 ->(箭头)表达式;

(String first, String second) -> first.length() - second.length();


2、表达式可以是一条语句,也可以是 {} 括号的代码块;

(String first, String second) -> {

return first.length() - second.length();

}


3、lambda 表达式没有参数时也要使用 () 表示空参数,就像方法没有参数;

() -> {

return System.out.println("lambda");

}


4、如果能够推导出参数的类型,那参数部分可以不使用类型;

(first, second) -> {

return first.length() - second.length();

};


5、只有一个参数时,且能够推导出参数类型,则可以不使用小括号;

first -> {

return first.length();

}


6、lambda 表达式有返回类型时:

①、一条语句不需要用 return 返回,因为可以推导出;

first -> first.length() ;

②、在 {} 代码块中的需要用 return 返回;

first -> {

return first.length();

};


7、lambda 表达式没有返回类型时,不需要使用 return;

first -> first.length() ;

first -> {

first.length();

};


2、函数式接口

1)任何只有一个抽象方法的接口都是函数式接口,如下就是一个自定义的函数式接口;

2)@FunctionalInterface,可以使用该注解标记函数式接口,当然也可以不用该注解标记。使用该注解有以下两个好处;

1、当在接口中再新加一个抽象方法时,会报编译错误,很明显的知道;

2、在 javadoc 文档中会标记自定义的接口是函数式接口;

3)lambda 表达式的代码块其实就是函数式接口的抽象方法的实现;

1、当一个函数式接口作为一个方法(A)的入参时,我们以前是用一个类实现该接口,并实现接口中的抽象方法,然后传实现类给方法(A),在执行的时候会执行实现类中的方法;

2、使用 lambda 表达式;

4)在 java 中 lambda 表达式只能是转换为函数式接口,即 lambda 表达式是传递给方法中函数式接口参数的;

5)lambda 表达式不能赋给 Object 类型的变量,因为 Object 类不是函数式接口,只能赋给函数式接口的变量,即只能用函数式接口来接收;

6)特定的函数式接口在 java.util.function 包中;


3、方法引用

1)方法引用可以认为是 lambda 表达式的简写;

2)方法引用和 lambda 表达式一样在赋值给函数式接口变量时会生成一个对象;

解析:

1、Arrays.sort 方法第二个参数是 Comparator 接口(是一个函数式接口),在传 lambda 表达式和方法引用时会生成一个对象传给 Comparator 接口,lambda 表达式的代码块或方法引用时的方法会成为该生成对象的对 Comparator 接口抽象方法的实现内容;

2、由编译器生成;

3)使用方法引用时如果遇到多个重载方法,编译器会选择一个最合适的重载方法;

4)方法引用的三种情况:

1、object::instanceMethod

等价于向方法传递参数的 lambda 表达式,

如:System.out::println <==> x -> System.out.println(x),这里 out 是一个对象,把参数 x 传递给 println 方法;


2、Class::instanceMethod

等价的 lambda 表达式是,第一个参数是作为隐式参数,后面的参数作为传递给方法的参数,

如:
String::compareToIgnoreCase <==> (x, y) -> x.compareToIgnoreCase(y),第一个参数 x 是隐式参数,也即调用的方法;


3、Class::staticMethod

等价的 lambda 表达式是,所有的参数都传递给静态方法,

如:Math::pow <==> (x, y) -> Math.pow(x, y);


5)只有当 lambda 表达式的体调用一个方法的时候,才能把 lambda 表达式重写为方法引用;

1、object::instanceMethod

2、Class::instanceMethod

3、Class::staticMethod

6)方法引用时可以使用 this / super 参数;

this::equals <==> x-> this.equals(x);

super::instanceMethod;


4、构造器引用

1)Person::new <==> (xxx...) -> new Person(xxx...);

构造器方法的选择是根据上下文自动选择的,会选择出合适的参数的构造器方法;

2)Person[]::new <==> n -> new Person[n];

3)不管是方法引用还是构造器引用,都会转为等价的 lambda 表达式,而 lambda 表达式会作为函数式接口的实现往下传;


5、变量作用域

1)在 lambda 表达式中可以访问所属方法或类中的变量;

2)lambda 表达式是传递给函数式接口的,相当于是函数式接口的实现,lambda 表达式使用所属方法中的变量,就相当于把变量传递给函数式接口的实现类的方法;

3)lambda 表达式使用所属方法中的变量时会存储一份该变量的值,即 lambad 表达式可以捕捉到外围作用域中变量的值;

4)lambda 表达式只可以引用值不会改变的外围作用中的变量;

5)lambda 表达式捕捉的变量必须是事实最终变量,事实最终变量是指该变量初始化之后就不会再赋值;

6)lambda 表达式中不能定义与外围作用域中同名的变量;

7)lambda 表达式内不能定义同名的变量;

8)在 lambda 表达式中使用 this 关键字时,该 this 关键字表示的 lambda 表达式所属方法所在的对象;

最近发表
标签列表