【函数式编程】Lambda表达式

Lambda表达式

什么是lambda表达式

lamda表达式是一种Java用于实现函数式接口 的一种书写形式

首先,它是一个书写形式,是一种语法规则不是什么函数之类的东西。

书写形式

既然Lambda是一种书写形式,那应该怎么书写呢?

类似于: (参数)->{逻辑体},

具体书写如下:

可以清晰的看到,后面的Comparator是使用Lambda表达式来书写的,这是因为Comparator是一个函数式接口。

函数式接口就能写成Lambda表达式的形式。

函数式接口

上面说到函数式接口,什么是函数式接口

  1. 首先它是一个接口
  2. 里面只有一个抽象方法
  3. 可以有默认方法和静态方法

总之!!!函数式接口只能有一个抽象方法,而且被@FunctionalInterface注解: 比如Comparator。

下面是去源码里截取的部分方法。

java 复制代码
@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
    default Comparator<T> reversed() {
        return Collections.reverseOrder(this);
    }
    public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
        return Collections.reverseOrder();
    }

你可以观察到里面有default(默认)static(静态)方法 , 但是只有一个抽象方法compare()

但是你能看见它好像还有一个抽象方法equals(), 先说结论这个不算是它的抽象方法,而是它从Object那里继承来的,写在这里只是表示实现这个接口的类必须去实现这个方法。但是呢,任何类都默认有实现,从Object那里继承来的实现,所以一般是不用再重写的

所以, Comparator算是一个函数式接口。

所有的函数式接口都可以使用Lambda,包括我们自己造的函数式接口:

java 复制代码
public class MyClass{
    public static void main(String[] args) {
        addMethod(5,6, (a,b)->{
            return a+b;
        });
    }
    public static void addMethod(int a, int b, MyFunction myFunction){

    }
}
@FunctionalInterface
interface MyFunction {
    int add(int a, int b);
}

java里的函数式接口Function

源码里的结构:

csharp 复制代码
@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);

有传参(T),有返回值(R)

看看怎么使用吧:

arduino 复制代码
public class MyClass{
    public static void main(String[] args) {
        System.out.println(method(5, o1 -> o1 - 1));
    }
    // 这里写上参数和返回值的类型哦
    public static int method(int a, Function<Integer, Integer> myFunction){
        return myFunction.apply(a);
    }
}

在要使用的地方传具体的类型即可,很简单

java里的函数式接口Supplier(供给者)

源码里的结构:

csharp 复制代码
@FunctionalInterface
public interface Supplier<T> {
    T get();
}

无传入,但是有返回值(T)。

使用:

arduino 复制代码
public class MyClass{
    public static void main(String[] args) {
        addMethod(5,6, ()-> 5);
    }
    // 这里定义返回类型
    public static void addMethod(int a, int b, Supplier<Integer> myFunction){}
}

java里的函数式接口Consumer(消费者)

csharp 复制代码
@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

有传入,无返回,白嫖怪

使用:

typescript 复制代码
public class MyClass{
    public static void main(String[] args) {
        method(5, (o1)-> {
            System.out.println("消费" + o1);
        });
    }
    // 定义参数类型
    public static void method(int a, Consumer<Integer> myFunction){
        myFunction.accept(a);
    }
}

java里的函数式接口Predicate(断言)

源码里的结构:

复合条件的返回true,不符合的返回false

java 复制代码
@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

使用:

typescript 复制代码
public class MyClass{
    public static void main(String[] args) {
        System.out.println(method(0, o -> o > 1));
    }
    public static boolean method(Integer integer ,Predicate<Integer> myFunction){
        return myFunction.test(integer);
    }
}

作用

对于我来说最直观的作用就是书写简便。

对于Java来说是有对性能的提升的:我们不使用lambda就只能使用匿名内部类,但是大多数情况下匿名内部类的效率是低于lambda的。

原因:对于匿名内部类,编译器会为每一个匿名内部类创建相应的类文件。一般的程序,往往回调接口会有很多。这样就会生成很多的类文件,因为类在使用之前需要加载类文件并进行验证,这个过程就会影响应用的性能。

Lambda表达式虽然推导到相应的函数式接口,但并没有编译成匿名内部类的方式来处理,而做成是直接方法调用。(为什么这样的逻辑我搞不懂,反正比匿名快)


然后Java还有其它内置接口,慢慢探索吧,我也用不到那么多。

下节预告: 【函数式编程】方法引用

相关推荐
bug菌23 分钟前
Java GUI编程进阶:多线程与并发处理的实战指南
java·后端·java ee
程序猿小D35 分钟前
第二百六十九节 JPA教程 - JPA查询OrderBy两个属性示例
java·开发语言·数据库·windows·jpa
极客先躯1 小时前
高级java每日一道面试题-2024年10月3日-分布式篇-分布式系统中的容错策略都有哪些?
java·分布式·版本控制·共识算法·超时重试·心跳检测·容错策略
夜月行者2 小时前
如何使用ssm实现基于SSM的宠物服务平台的设计与实现+vue
java·后端·ssm
程序猿小D2 小时前
第二百六十七节 JPA教程 - JPA查询AND条件示例
java·开发语言·前端·数据库·windows·python·jpa
Yvemil72 小时前
RabbitMQ 入门到精通指南
开发语言·后端·ruby
sdg_advance2 小时前
Spring Cloud之OpenFeign的具体实践
后端·spring cloud·openfeign
潘多编程2 小时前
Java中的状态机实现:使用Spring State Machine管理复杂状态流转
java·开发语言·spring
_阿伟_2 小时前
SpringMVC
java·spring
代码在改了3 小时前
springboot厨房达人美食分享平台(源码+文档+调试+答疑)
java·spring boot