【函数式编程】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还有其它内置接口,慢慢探索吧,我也用不到那么多。

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

相关推荐
Han.miracle几秒前
MySQL InnoDB:MVCC、记录锁、间隙锁、二级索引MVCC底层原理
java·开发语言
不停喝水26 分钟前
【前端转全栈java速通课】 项目实战④7-11节 操作数据库-登录-注册-修改密码-注销-mubatis-plus简化crud-
java·前端·数据库
y1su32 分钟前
Leetcode 二分模板
java·数据结构·算法·leetcode·排序算法
霸道流氓气质1 小时前
多Agent通信机制与协议设计完全指南:从FIPA-ACL到A2A/MCP的Java生产级实战
java·开发语言
007张三丰1 小时前
C/C++ 内存管理详解:从内存分布到 new/delete 底层原理
java·c语言·c++·内存管理
骇客野人1 小时前
Java BIO / NIO / AIO 完整详解 + 编程技巧
java·开发语言·nio
霸道流氓气质1 小时前
OpenTelemetry 入门与实战:Java Agent、Spring Boot Starter与LLM调用追踪示例
java·开发语言·spring boot
m0_587383001 小时前
24 小时自助健身房系统软件开发实战指南与案例解析
java·spring boot·spring·系统架构·需求分析
栖凤1 小时前
Java 的 try-catch 在 Agent 里失效了,我用了 5 个模式才兜住
java·前端·python