java lambda表达式、方法接口的来龙去脉

问题描述

有这样的需求,我们能够不改变代码时候,通过增加代码扩展功能,通常可以定义一个接口,通过实现接口扩展功能。如下例子:

定义接口:

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);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值