问题描述
有这样的需求,我们能够不改变代码时候,通过增加代码扩展功能,通常可以定义一个接口,通过实现接口扩展功能。如下例子:
定义接口:
package lambatest;
public interface Animal {
String eat();
}
实现接口
package lambatest;
public class CatImpl implements Animal{
@Override
public String eat() {
return "猫吃鱼";
}
}
测试代码:
package lambatest;
/**
* @ClassName: AnimalTest
* @Description:
* @Author:10262863
* @Date 2022/5/16
* @Version 1.0
*/
public class AnimalTest {
public void eat(Animal animal){
System.out.println(animal.eat());
}
public static void main(String[] args) {
//我们要实现猫吃鱼怎么办呢?
AnimalTest animalTest = new AnimalTest();
//通常做法,我们要有一个猫的实现类
CatImpl cat = new CatImpl();
//多态
animalTest.eat(cat);
}
}
那有没有其他方法,可以不显示写实现类,而完成这个功能呢?答案是:匿名内部类。
匿名内部类
接着上面的问题,我们使用匿名内部类实现上面的功能:
public class AnimalTest {
public void eat(Animal animal){
System.out.println(animal.eat());
}
public static void main(String[] args) {
//我们要实现猫吃鱼怎么办呢?
AnimalTest animalTest = new AnimalTest();
//使用匿名内部类实现猫吃鱼
animalTest.eat(new Animal() {
@Override
public String eat() {
return "猫吃鱼";
}
});
}
}
该匿名内部类编译后被显示为lambatest/AnimalTest$1,如果有多个匿名类,依次命名下去。
lambda表达式
上面的匿名内部类还可以使用java语法糖进一步简化,前提是接口要是方法接口,需要对Animal接口进行改造,改造如下:
package lambatest;
@FunctionalInterface
public interface Animal {
String eat();
}
只需要加@FunctionalInterface注解就可以变为方法接口。现在我们来进一步简化匿名内部类的书写。
public class AnimalTest {
public void eat(Animal animal){
System.out.println(animal.eat());
}
public static void main(String[] args) {
//我们要实现猫吃鱼怎么办呢?
AnimalTest animalTest = new AnimalTest();
//使用lambda表达式实现猫吃鱼
animalTest.eat(() -> {
return "猫吃鱼";
});
}
}
lambda定义的一般形式
(parameter1,parameter2,etc) -> {
//expression
......
};
::如何使用
::是语法糖的进一步简化,也是lambda表达式,用法如下:
HashSet<String> stringHashSet = new HashSet<>();
stringHashSet.add("dsdsdsdsdsds");
stringHashSet.add("2");
stringHashSet.add("2");
stringHashSet.forEach(e-> System.out.println(e));
stringHashSet.forEach(System.out::println);
System.out.println的参数和传递的参数element 的类型完全匹配,所以这样的时候就可以简化为:forEach(System.out::println)。
::到底是什么?
https://stackoverflow.com/questions/20001427/double-colon-operator-in-java-8
::是一种方法引用,开始提到的需求也可以写成如下形式:
Function<Animal, String> eat = Animal::eat;
String apply = eat.apply();
System.out.println(apply);