Lambda表达式与函数式接口的关系
-
Lambda 表达式是一种语法糖,不是对象,只是一种语法,无法单独直接使用,需要结合函数式接口使用。
如:直接使用 Lambda 表达式,无法知道该表达式是做什么的(传入的参数是什么,进行怎样的操作,输出什么结果)。
(a, f) -> a + " eat " + f -
函数式接口是指有且仅有一个抽象方法的接口。
如:结合函数式接口,能够分析出具体 Lamdba 表达式的意义。
// 函数式接口 public interface Animal { String eat(String animal, String food); } // 该 Lambda 表达式创建一个 Animal 匿名内部类对象,并实现了其中的抽象方法。 Animal animal = (a, f) -> a + " eat " + f; -
总结:Lambda 表达式是一种语法,不能脱离函数式接口直接使用,每一个 Lambda 表达式必须有一个函数式接口与之对应。可以使用 Lambda 表达式简洁地实例化函数式接口的实例对象。
Lambda 表达式的理解
-
Lambda 表达式可以实现同匿名内部类相同的效果,可以取代大部分的匿名内部类,可以认为是对匿名内部类的一种简化。(当 Lambda 表达式不会写时,可以先写出对应的匿名内部类,然后再使用 Idea 中的快捷键转换成对应的 Lambda 表达式)
为什么是取代大部分匿名内部类?不是所有的匿名内部类可以简化为 Lambda 表达式,只有实现函数式接口的匿名内部类才可以使用 Lambda 表达式来简化替代。
如:
// 函数式接口 public interface Animal { String eat(String animal, String food); } // 创建 Animal 匿名内部类对象 Animal animal = new Animal() { @Override public String eat(String a, String f) { System.out.println("Lambda 表达式理解"); return a + " eat " + f; } }; // 使用 Lambda 表达式简化 Animal 匿名内部类对象的创建 Animal animal = (a, f) -> { System.out.println("Lambda 表达式理解"); return a + " eat " + f; };
方法引用
- 方法引用是 Lambda 表达式的一种简化,可以认为是 Lambda 表达式的一个语法糖。
当实现函数式接口中的抽象方法时,实现的方法体只有一行代码。
类名 :: 静态方法
- 重写函数式接口中的抽象方法时,只调用某个类的静态方法,把抽象方法中的所有参数按照顺序传入到这个静态方法中。静态方法中的参数要与抽象方法中的参数一一对应。
// 函数式接口 public interface Animal { String feature(String a, int age); } // 匿名内部类 Animal animal = new Animal() { @Override public String feature(String a,int age) { return Cat.getAge(a,age); } }; // Lambda 表达式 Animal animal = (a, age) -> Cat.getAge(a,age); // 类名 :: 静态方法引用 Animal animal = Cat::getAge; // 工具类 public class Cat { String eat(String a, String f){ return a + " eat " + f; } public static String getAge(String a,int age){ return a+" "+String.valueOf(age); } }
对象 :: 实例方法
-
重写函数式接口中的抽象方法时,只调用某个对象的实例方法,把抽象方法中的所有参数按照顺序传入到这个实例方法中。实例方法中的参数要与抽象方法中的参数一一对应。
// 函数式接口 public interface Animal { String feature(String a, String f); } // 创建某个对象 Cat cat = new Cat(); // 对象 // 匿名内部类 Animal animal = new Animal() { @Override public String feature(String a, String f) { return cat.eat(a, f); } }; // Lambda 表达式 Animal animal = (a, f) -> cat.eat(a, f); // 对象 :: 实例方法引用 Animal animal = cat::eat; // 工具类 public class Cat { String eat(String a, String f){ return a + " eat " + f; } public static String getAge(String a,int age){ return a+" "+String.valueOf(age); } }
类名 :: 实例方法
- 重写函数式接口中的抽象方法时,只调用抽象方法中第一个入参对象的实例方法,把抽象方法中剩余的所有参数按照顺序传入到这个实例方法中。实例方法中的参数要与抽象方法中剩余的参数一一对应。
// 函数式接口
public interface Animal {
String feature(Cat cat, String a, String f);
}
// 匿名内部类
Animal animal = new Animal() {
@Override
public String feature(Cat cat, String a, String f) {
return cat.eat(a, f);
}
};
// Lambda 表达式
Animal animal = (cat, a, f) -> cat.eat(a, f);
// 类名 :: 实例方法引用
Animal animal = Cat::eat;
// 工具类
public class Cat {
String eat(String a, String f){
return a + " eat " + f;
}
public static String getAge(String a,int age){
return a+" "+String.valueOf(age);
}
}
类名 :: 构造方法
- 重写函数式接口中的抽象方法时,只调用某个类的构造方法,把抽象方法中的所有参数按照顺序传入到这个构造方法中。构造方法中的参数要与抽象方法中的参数一一对应。
// 函数式接口
public interface Animal {
Cat feature(String a, String f);
}
// 匿名内部类
Animal animal = new Animal() {
@Override
public Cat feature(String a, String f) {
return new Cat(a, f);
}
};
// Lambda 表达式
Animal animal = (a, f) -> new Cat(a, f);
// 类名 :: 构造方法引用
Animal animal = Cat::new;
// 工具类
public class Cat {
public Cat(String a, String f){};
String eat(String a, String f){
return a + " eat " + f;
}
public static String getAge(String a,int age){
return a+" "+String.valueOf(age);
}
}
文章介绍了Lambda表达式作为Java中的语法糖,需要与函数式接口结合使用。它简化了匿名内部类的实现,特别是对于实现有且仅有一个抽象方法的接口。文章还详细讲解了方法引用,包括类名::静态方法、对象::实例方法、类名::实例方法和类名::构造方法的情况,这些都是Lambda表达式的简化形式。
899

被折叠的 条评论
为什么被折叠?



