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

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

相关推荐
许彰午2 小时前
14_Java泛型完全指南
java·windows·python
智慧物业老杨2 小时前
司法绿色通道下的物业纠纷数智化解决方案——基于“三优先“机制的全流程技术落地实践
java·django
2601_961194022 小时前
2026初级会计实务公式总结大全|计算题公式手册PDF
java·spring·eclipse·pdf·tomcat·hibernate
做个文艺程序员2 小时前
第1篇:K8s 核心概念精讲:Pod、Deployment、Service 与 Namespace——Java 开发者快速上手指南
java·云原生·容器·kubernetes·容器编排
大鸡腿同学3 小时前
AI 知识库搜索不准?问题出在分块
后端
夕颜1114 小时前
Multica 使用心得介绍
后端
小欣加油5 小时前
leetcode3751 范围内总波动值I
java·数据结构·c++·算法·leetcode
闪电悠米5 小时前
黑马点评-Redisson-01_why_redisson
java·服务器·网络·数据库·缓存·wpf
星轨zb5 小时前
LangChain4j 集成 Spring Boot:会话记忆 NPE 的根源与 ChatMemoryProvider 正确配置
java·spring boot·后端·langchain4j
JAVA9655 小时前
JAVA面试-并发篇 05-并发包AQS队列实现原理是什么
java·开发语言·面试