首页 文章详情

【java基础】Lambda表达式

码农有道公众号 | 67 2022-06-12 22:54 0 0 0
UniSMS (合一短信)

Lambda表达式介绍

Java支持Lambda 表达式始于Java 8,它的出现简化了函数式接口匿名内部类的语法。使用Lambda表达式可以让我们的代码更少,看上去更简洁,代码更加灵活。但也有它的缺点所在,如果Lambda表达式用的不好的话,调试运行和后期维护比较麻烦。

Lambda只能接受函数式接口,所谓的函数式接口指的是只能有一个抽象方法的接口。

Lambda表达式语法

Lambda表达式通过操作符->分为两个部分:

  • • 左侧:指定了Lambda表达式所需要的所有参数。

  • • 右侧指定了Lambda体,即Lambda表达式所要执行的功能。

Lambda表达式的基本语法结构如下,当然,这里只是简单的Lambda 表达式的应用。

到目前为止,我们对Lambda表达式有了基本的认识,下面用几个简单的例子来让我们好好理解一下Lambda表达式的使用,看看Lambda是怎样简化了函数式接口匿名内部类的。

public class LambdaExample {
    public static void main(String[] args) {
        //普通写法(匿名内部类)
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Ordinary Writing");
            }
        });
        thread.start();

        //Lambda写法。无参无返回void
        Thread thread1 = new Thread(() -> System.out.println("Lambda Writing"));
        thread1.start();
    }
}

******************【运行结果】******************
Ordinary Writing
Lambda Writing

函数式接口

前面讲了使用Lambda表达式的前提是函数式接口,所以接下来学习一下函数式接口。

函数式接口介绍

函数式接口的定义:只允许有一个抽象方法的接口,那么它就是一个函数式接口。针对函数式接口,官方给我们提供了一个注解@FunctionalInterface,该注解会检查它是否是一个函数式接口,所以如果我们需要自定义一个函数式接口的话,可以在接口类的上方声明@FunctionalInterface。

需要注意的是,数式接口虽然规定只能有一个抽象方法,但是同时可以有多个非抽象方法(如静态方法,默认方法,私有方法)。下面是一个自定义的函数式接口:

@FunctionalInterface
public interface FunctionalInterface {
    /**
     * 抽象方法(只能有一个)
     */

    void method();
    //void method1();再定义一个会提示:找到多个抽象方法

    /**
     * 默认方法,必须用default修饰
     */

    default void defaultMethod() {
        System.out.println("默认方法...");
    }

    /**
     * 静态方法方法
     */

    static void staticMethod() {
        System.out.println("静态方法...");
    }
}

四大类型接口

Java8中增加了一个包:java.util.function。它们里面包含了常用的函数式接口,该包下定义的函数式接口非常多,主要有四大类:

可以看出四种函数式接口抽象方法的特点如下:

  •  消费型接口:有参数传入,无结果返回。

  •  供给型接口:无参数传入,但是有返回值

  •  判断型接口:有参传入,但是返回值类型是boolean结果。

  • • 功能型接口:既有参数传入又有结果值返回

四种函数式接口用法简单举例如下:

/**
 * 内置最常用的四种函数式接口
 */

class FunctionalnterfaceTest{
    //消费型接口
    public void test0(){
        Consumer<String> consumer = s -> System.out.println("[Consumer<T>]--->" + s);
        consumer.accept("hello");
    }

    //供给型接口
    public void test1() {
        Supplier<String> supplier = () ->  "hello";
        System.out.println("[Supplier<T>]--->" + supplier.get());
    }

    //判断型接口
    public void test2() {
        Predicate<String> predicate = s -> s.equals("hello");
        System.out.println("[Predicate<T>]--->" + predicate.test("hello"));
    }

    //功能性接口
    public void test3() {
        Function<String, String> function = (s) -> {
            return "hello" + s;
        };
        System.out.println("[Function<T, R>]--->" + function.apply("666"));
    }
}

public class FunctionalnterfaceExample {
    public static void main(String[] args) {
        FunctionalnterfaceTest functionalnterfaceTest = new FunctionalnterfaceTest();
        functionalnterfaceTest.test0();
        functionalnterfaceTest.test1();
        functionalnterfaceTest.test2();
        functionalnterfaceTest.test3();
    }
}

******************【运行结果】******************
[Consumer<T>]--->hello
[Supplier<T>]--->hello
[Predicate<T>]--->true
[Function<T, R>]--->hello666

其实,这四种函数式接口每种都有其变种形式,如消费型接口有如下几种形式:


不过尽管形式很多,但是用法其实和最基本的用法差不多,这里就不一一介绍了。

本文源码地址:
https://github.com/qinlizhong1/javaStudy/tree/master/javaExample/src/main/java/java8

本文示例代码环境:
操作系统:macOs 12.1
JDK版本:12.0.1
maven版本: 3.8.4

👆扫描上方二维码关注

good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter