目录
Lambda表达式是一个匿名函数,Java在JDK1.8引入Lambda表达式。
结构:(参数列表)->{Lambda体:代码块,也就是表达式要运行的功能}
标准写法由下面几点构成:
例如:(int x, int y)->{return x + y;}
在接口上标记@FunctionalInterface说明该接口是一个函数式接口。
无论接口声明中是否存在@FunctionalInterface注解,编译器都会将满足函数式接口定义的任何接口视为函数式接口。
函数式接口的实例可以使用lambda表达式、匿名内部类、实现接口方法的类来创建。
函数式接口需满足以下条件
如果接口声明了一个覆盖 java.lang.Object 的公共方法之一的抽象方法,这不会进入抽象方法计数,因为接口的任何实现类都具有来自 java.lang.Object 或其他地方的实现。
- @FunctionalInterface
- public interface TestInterface {
- //常量:编译器都会加上public final标识
- String name = "name";
-
- //编译器都会加上public abstract标识
- String get();
-
- static void staticTest(){
- System.out.println("staticTest");
- }
-
- default void defaultTest(){
- System.out.println("defaultTest");
- }
-
- boolean equals(Object o);
- }
可参考:
FunctionalInterface注解_qinghuazs的博客-CSDN博客_functionalinterface注解
普通用法:(int x, int y)->{return x + y;}
精简语法:
1、参数的类型可省略(JVM会主动识别需要实现的方法确定参数的类型)
2、假如只有一个参数,()可以省略
3、如果方法体只有一个语句,{}可以省略
4、如果方法体唯一的语句是return返回语句,那么{}和return要同时省略
5、若对象的方法或类的静态方法,和接口的方法返回值、参数列表一致,且对象的方法或类的静态方法刚好满足接口方法实现的需求,则可采用方法引用
调用方式:对象::非静态方法
类::静态方法
类::非静态方法(适用条件参考2.7节)
注意:在方法引用中,不能通过对象去引用静态方法,例如对象::静态方法
- @FunctionalInterface
- public interface TestInterface {
-
- void get();
-
- }
- @Test
- public void test15(){
- TestInterface testInterface = ()->{
- System.out.println("无参无返回值");
- };
- testInterface.get();
-
- //精简语法
- testInterface = () -> System.out.println("无参无返回值");
- testInterface.get();
- }
- @FunctionalInterface
- public interface TestInterface {
-
- String get();
-
- }
- @Test
- public void test15(){
- TestInterface testInterface = ()->{
- return "无参有返回值";
- };
- System.out.println(testInterface.get());;
-
- //精简语法
- testInterface = () -> "无参有返回值";
- System.out.println(testInterface.get());;
- }
- @FunctionalInterface
- public interface TestInterface {
-
- void get(String value);
-
- }
- @Test
- public void test15(){
- TestInterface testInterface = (value)->{
- System.out.println(value);
- };
- testInterface.get("有参无返回值");
-
- //精简语法
- testInterface = value -> System.out.println(value);
- testInterface.get("有参无返回值");
- //方法引用
- testInterface = System.out::println;
- testInterface.get("有参无返回值");
- }
- @FunctionalInterface
- public interface TestInterface {
-
- int get(int a, int b);
-
- }
- @Test
- public void test15(){
- TestInterface testInterface = (a, b)->{
- return a + b;
- };
- System.out.println(testInterface.get(1, 2));
-
- //精简语法
- testInterface = (a, b) -> a + b;
- System.out.println(testInterface.get(1, 2));
-
- }
- @FunctionalInterface
- public interface TestInterface {
-
- int get(int a, int b);
-
- }
- package com.mzp.component;
-
- public class Demo {
- public int getValue(int a, int b){
- return a + b;
- }
- }
- @Test
- public void test15(){
- TestInterface testInterface = (a, b)->{
- return a + b;
- };
- System.out.println(testInterface.get(1, 2));
-
- //精简语法
- testInterface = (a, b) -> a + b;
- System.out.println(testInterface.get(1, 2));
-
- Demo demo = new Demo();
- //对象::方法
- testInterface = demo::getValue;
- System.out.println(testInterface.get(1, 2));
- }
- package com.mzp.component;
-
- public class Demo {
- public static int getStaticValue(int a, int b){
- return a + b;
- }
- }
- @Test
- public void test15(){
- TestInterface testInterface = (a, b)->{
- return a + b;
- };
- System.out.println(testInterface.get(1, 2));
-
- //精简语法
- testInterface = (a, b) -> a + b;
- System.out.println(testInterface.get(1, 2));
-
- //类::静态方法
- testInterface = Demo::getStaticValue;
- System.out.println(testInterface.get(1, 2));
- }
如果Lambda表达式的方法体刚好是排在第一的参数对象调用对象自身的方法(排除静态方法),且对象的方法参数和Lambda参数列表从第二位参数开始一一对应(参数类型、个数),
则可使用类::非静态方法。
例如
- package com.mzp.component.functional;
-
- import com.mzp.component.Demo;
-
- @FunctionalInterface
- public interface TestInterface {
-
- int get(Demo a, String b, int c);
-
- }
- package com.mzp.component;
-
- public class Demo {
- private String name = "original";
-
- public Demo(){
-
- }
-
- public Demo(String name){
- this.name = name;
- }
-
- public int add(String a, int b){
- System.out.println(name);
- return b;
- }
- }
- @Test
- public void test15(){
- Demo demo = new Demo("update");
- TestInterface testInterface = (a, b, c)->{
- return a.add(b, c);
- };
- System.out.println(testInterface.get(demo,"1", 2));
-
- //精简语法
- testInterface = (a, b, c) -> a.add(b, c);
- System.out.println(testInterface.get(demo,"1", 2));
-
- //类::非静态方法
- testInterface = Demo::add;
- System.out.println(testInterface.get(demo,"1", 2));
- }
注意:若是Demo类中刚好有名称相同的静态方法和非静态方法,且函数式接口的第一个参数类型为Demo,通过lambda表达式创建函数式接口实例,
静态方法通过方法引用(类::静态方法)匹配到,
非静态方法也通过特殊方法引用(类::方法)匹配到,编译器则会报错,匹配到多个实现方法。
例如
函数式接口方法如图
- @FunctionalInterface
- public interface MyFunctionalInterface {
- int add(Demo a, int b);
- }
Demo类如图
- public class Demo {
- public static int add(Demo demo, int b){
- return b;
- }
-
- public int add(int b){
- return b;
- }
- }
通过lambda表达式创建函数式接口实例报错
