美文网首页
lambda表达式

lambda表达式

作者: Java_Explorer | 来源:发表于2019-04-23 23:00 被阅读0次

    概要:

    1. 函数式编程特性
    2. lambda表达式语法及应用场景
    3. Java 8自带函数式接口详解

    一、函数式编程特性


    1. lambda表达式简介

    lambda表达式,也可称为闭包,它是推动Java 8发布的最重要新特性。
    lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
    使用lambda表达式可以使代码变得更加简洁紧凑。

    如下示例中起到的作用是功能类似的:

    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("Hello World");
        }
    }).start();
    
    new Thread(() -> System.out.println("Hello World")).start();
    

    java 8加入lambda之后,就可以像javascript之类的函数式语言一样,将函数逻辑作为参数或属性进行传递。

    // 将函数执行逻辑以参数的形式传递给方法
    sayHello(str -> Integer.parse(str) + 1);
    
    private void sayHello(Function<String, Integer> convert) {
        System.out.println("Hello World");
        System.out.println(convert.apply("29"));
    }
    

    2. 为什么要使用lambda表达式?

    一些会随着业务场景而变化的逻辑则以参数的形式传递到方法中,采用行为参数化可以让程序更加的通用,以应对频繁变更的需求。
    这里以java 8 in action中的例子进行说明,考虑一个业务场景,假设我们需要通过程序对苹果按照一定的条件进行筛选,我们先定义一个苹果类:

    // 获取 red 红颜色的苹果
    public List<Apple> getRedApple() {
        List result = new ArrayList();
        for (Apple apple : appleStore) {
            if (apple.getColor().equals("red")) {
                result.add(apple);
            }
        }
        return result;
    }
    
    // 基于颜色获取苹果
    public List<Apple> getAppleByColor(String color) {
        List result = new ArrayList();
        for (Apple apple : appleStore) {
            if (apple.getColor().equals(color)) {
                result.add(apple);
            }
        }
        return result;
    }
    
    // 基于表达式获取苹果
    public List<Apple> getAppleBy(Predicate<Apple> predicate) {
        List result = new ArrayList();
        for (Apple apple : appleStore) {
            if (predicate.test(apple)) {
                result.add(apple);
            }
        }
        return result;
    }
    

    二、lambda表达式语法及应用场景


    1. 函数式接口

    lambda前置条件:必须是函数式接口才可以使用lambda表达式

    函数式接口特征:

    • 接口中标注了@FunctionInterface注解
    • 接口中只有一个抽象方法,则该接口会被编译器自动识别成函数式接口
    • 接口中有一个抽象方法,同时包含了Object类的其他抽象方法,则该接口也会被识别成函数式接口

    2. lambda表达式三种编写方式

    expression:单条语句表达式
    statement:语句块
    reference:方法引用

    expression单条语句表达式

    只能是一个完整的语句。
    expression表达式中不需要写return关键字,解释器会自动将表达式的计算结果进行返回。

    示例演示:
    (参数) -> 表达式

    statement语句块

    statement语句块通过大括号{}包裹多条语句,如果是需要返回结果的接口,必须显式的加上return指明返回的变量

    示例演示:
    (参数) -> {}

    reference方法引用

    如果某个方法在结构上与lambda表达式中对应方法是匹配的,那么就可以直接引用给lambda表达式。其总共包含4种引用类型,语法格式见表格:

    类型 语法
    基于实例方法引用 object::methodName
    构造方法引用 className::new
    基于参数实例方法引用 className::methodName
    静态方法引用 className::staticMethodName

    示例演示

    构造方法引用演示

        public interface MyLoves {
            List<String> getAllLove();
        }
    
        @Test
        public void test2() {
            // 构造方法引用
            MyLoves loves = ArrayList::new;
            loves.getAllLove();
        }
    

    基于参数实例方法引用

    public interface MyLoves {
        void compare(String wife, String mom);
    }
    
    @Test
    public void test() {
        MyLoves love = String::compareTo;
    }
    

    3. lambda表达式主要特征总结

    • 可选类型声明: 不需要声明参数类型,编译器可以统一识别参数值。
    • 可选的参数圆括号: 一个参数无需定义圆括号,但多个参数需要定义圆括号。
    • 可选的大括号: 如果主体包含了一个语句,就不需要使用大括号。
    • 可选的返回关键字: 如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指明表达式返回了一个数值。

    4. lambda表达式常见应用场景

    对象排序
    动态代理
    事件监听
    条件过滤
    启动线程

    三、Java 8自带函数式接口详解

    函数式接口 参数类型 返回类型 用途
    Consumer T void 对T类型参数操作,无返回结果,包含方法void accept(T t)
    Supplier T 返回T类型参数,方法是T get()
    Function T R 对T类型参数操作,返回R类型参数,包含方法R apply(T t)
    BiFunction 与Function类似,不同在于接收两个参数
    BinaryOperator 类似于BiFunction,不同在于所有参数和返回结果必须是一样的
    Predicate T boolean T 断言型接口,对类型T进行条件筛选操作
    BiPredicate T 断言型接口,接收两个参数进行断言

    相关文章

      网友评论

          本文标题:lambda表达式

          本文链接:https://www.haomeiwen.com/subject/jtxsgqtx.html