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

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

相关推荐
indexsunny3 小时前
互联网大厂Java求职面试实战:Spring Boot微服务与Redis缓存场景解析
java·spring boot·redis·缓存·微服务·消息队列·电商
无心水3 小时前
【分布式利器:腾讯TSF】7、TSF高级部署策略全解析:蓝绿/灰度发布落地+Jenkins CI/CD集成(Java微服务实战)
java·人工智能·分布式·ci/cd·微服务·jenkins·腾讯tsf
28岁青春痘老男孩8 小时前
JDK8+SpringBoot2.x 升级 JDK 17 + Spring Boot 3.x
java·spring boot
方璧8 小时前
限流的算法
java·开发语言
元Y亨H8 小时前
Nacos - 服务注册
java·微服务
曲莫终8 小时前
Java VarHandle全面详解:从入门到精通
java·开发语言
一心赚狗粮的宇叔8 小时前
中级软件开发工程师2025年度总结
java·大数据·oracle·c#
奋进的芋圆9 小时前
DataSyncManager 详解与 Spring Boot 迁移指南
java·spring boot·后端
计算机程序设计小李同学9 小时前
个人数据管理系统
java·vue.js·spring boot·后端·web安全
小途软件9 小时前
用于机器人电池电量预测的Sarsa强化学习混合集成方法
java·人工智能·pytorch·python·深度学习·语言模型