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

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

相关推荐
新手小袁_J3 分钟前
JDK11下载安装和配置超详细过程
java·spring cloud·jdk·maven·mybatis·jdk11
呆呆小雅3 分钟前
C#关键字volatile
java·redis·c#
Monly214 分钟前
Java(若依):修改Tomcat的版本
java·开发语言·tomcat
Ttang236 分钟前
Tomcat原理(6)——tomcat完整实现
java·tomcat
goTsHgo7 分钟前
在 Spring Boot 的 MVC 框架中 路径匹配的实现 详解
spring boot·后端·mvc
钱多多_qdd17 分钟前
spring cache源码解析(四)——从@EnableCaching开始来阅读源码
java·spring boot·spring
waicsdn_haha19 分钟前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk
Q_192849990629 分钟前
基于Spring Boot的摄影器材租赁回收系统
java·spring boot·后端
Code_流苏32 分钟前
VSCode搭建Java开发环境 2024保姆级安装教程(Java环境搭建+VSCode安装+运行测试+背景图设置)
java·ide·vscode·搭建·java开发环境
良许Linux34 分钟前
0.96寸OLED显示屏详解
linux·服务器·后端·互联网