Java8 Lambda 介绍

简介: Lambda是一段可以传递的代码,可以被多次执行。当然,不使用Lambda表达式也可以写出同样的代码,对比如下,可以看到lambda的写法简洁很多。 public interface Invocable { R invoke(T input); } public static void main(String[] args) {

Lambda是一段可以传递的代码,可以被多次执行。当然,不使用Lambda表达式也可以写出同样的代码,对比如下,可以看到lambda的写法简洁很多。

public interface Invocable<T,R> {
    R invoke(T input);
}

public static void main(String[] args) {
    myInvoke("str", new Invocable<String, String>() {
        @Override
        public String invoke(String input) {
            return "MyInvocable#invoke --> " + input;
        }
    });

    myInvoke("str", (input) -> "MyInvocable#invoke --> " + input);
}

private static void myInvoke(String str, Invocable invocable) {
    System.out.println(invocable.invoke(str));
}

Lambda语法

Lambda语法格式如下,如果一个表达式无法完整表达逻辑,那就就写成一个代码块,用花括号括起。

(参数...) -> [表达式;代码块]

示例:

    //表达式
    (String first, String second) -> Integer.compare(first.length(), second.length());
    //代码块
    (String first, String second) -> {
        if (first.length() < second.length()) return -1;
        else if (first.length() > second.length()) return 1;
        else return 0;
    }
    //无入参
    () -> {
        for (int i = 0; i < 10; i++) doSomeThing();
    }
    //自动推导入参类型
    Comparator comp = (first, second) -> Integer.compare(first.length(), second.length());

函数式接口

对于只包含一个抽象方法的接口,就可以通过lambda表达式来创建该接口的对象啦,这种接口就叫做函数式接口。java.util.function包中预定义了好多函数式接口,并且同意标记上了注解【@FunctionalInterface】。自定义的函数式接口也建议加上这个注解,因为编译器会检查该实体,是否只包含一个抽象方法的,同时也更加清晰可读。
例如:

    Map<Integer, User> userMap = Stream.of(new User(0, "张三", 18, 0), new User(0, "张四", 19, 0), new User(0, "老张", 20, 1))
            .collect(Collectors.toMap(User::getId, item -> item));

这里的toMap方法接收的输入参数就是Function函数:

public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                Function<? super T, ? extends U> valueMapper) {

其他常见预定义函数的说明可以参见上一篇文章(http://www.atatech.org/articles/61907

方法引用和构造器引用

方法引用:

    //对象::实例方法:
    instance::method --> (input1,input2...) -> instance.method(input1,input2...)

    //类::静态方法:
    class::staticMethod --> (input1,input2...) -> class.staticMethod(input1,input2...)

    //类::实例方法:
    class::method --> (input1,input2,input3...) -> input1.method(input2,input3...)

构造器引用:

    
    List<String> list = Arrays.asList("a", "b");
    list.stream().map(MyClass::new);

构造器引用会自动适配一个合适的构造函数,例如上面的示例会适配一个入参为一个String类型的构造函数。

Lambda的闭包语法糖

在java中原有的闭包:

public static Supplier<Integer> testClosure() {
    final int i = 1;
    return new Supplier<Integer>() {
        @Override
        public Integer get() {
            return i;
        }
    };
}

public interface Supplier<T> {
    T get();
}

此处变量i是testClosure方法的内部变量,但是我们在匿名内部函数get中却返回了 i;内部变量 i 的生存周期延长了,并且使得变量 i 可以被外部函数所引用,这就是闭包。注意变量 i 必须为final,否则会编译错误。

在Lambda中的闭包:

public static Supplier<Integer> testClosure() {
    int i = 1;
    //i++;
    return () -> {
        return i;
    };
}

此处 i 不需要定义为final,但是这仅仅是一个语法糖,事实上任何对 i 的value的变更一样会引起语法错误。

延迟执行

lambda表达式都是延迟执行的,如果需要立即执行一段代码,就没必要使用lambda表达式了,就好像如果需要立即执行就没必要使用匿名内部类一样。lambda表达式可以在另一个线程中执行,可以多次运行,按需运行,在某个正确的时机(事件触发,算法运行的某个时间点)运行。

例如,常用的log记录方式如下:

    log.info("x:" + x + ",y:" + y);

参数会立即计算完成再传递给info方法,此时会判断日志级别,如果符合info输出才会打印日志,如果为debug等info不输出的情况,会忽略当前信息,但是呢参数已经计算过了。做了一次无用功。此时如果改为lambda延迟执行,则不会出现这种无谓的计算。如下:

    log.info(() -> "x:" + x + ",y:" + y);

总结

迟来的特性,哈哈,不过还是带来了很多便利的。

目录
相关文章
|
安全 Java API
Java中的Lambda表达式:简洁与功能的结合
Java中的Lambda表达式:简洁与功能的结合
604 211
|
SQL JSON 安全
Java 8 + 中 Lambda 表达式与 Stream API 的应用解析
摘要:本文介绍了Java 8+核心新特性,包括Lambda表达式与Stream API的集合操作(如过滤统计)、函数式接口的自定义实现、Optional类的空值安全处理、接口默认方法与静态方法的扩展能力,以及Java 9模块化系统的组件管理。每个特性均配有典型应用场景和代码示例,如使用Stream统计字符串长度、Optional处理Map取值、模块化项目的依赖声明等,帮助开发者掌握现代Java的高效编程范式。(150字)
325 1
|
SQL Rust Java
怎么理解Java中的lambda表达式
Lambda表达式是JDK8引入的新语法,用于简化匿名内部类的代码写法。其格式为`(参数列表) -&gt; { 方法体 }`,适用于函数式接口(仅含一个抽象方法的接口)。通过Lambda表达式,代码更简洁灵活,提升Java的表达能力。
462 4
|
Java 编译器 API
Java Lambda 表达式:以 Foo 接口为例深入解析
本文深入解析了 Java 8 中 Lambda 表达式的用法及其背后的函数式接口原理,以 `Foo` 接口为例,展示了如何通过简洁的 Lambda 表达式替代传统匿名类实现。文章从 Lambda 基本语法、函数式接口定义到实际应用层层递进,并探讨默认方法与静态方法的扩展性,最后总结常见误区与关键点,助你高效优化代码!
411 0
|
Java API 开发者
Java中的Lambda表达式与Stream API的协同作用
在本文中,我们将探讨Java 8引入的Lambda表达式和Stream API如何改变我们处理集合和数组的方式。Lambda表达式提供了一种简洁的方法来表达代码块,而Stream API则允许我们对数据流进行高级操作,如过滤、映射和归约。通过结合使用这两种技术,我们可以以声明式的方式编写更简洁、更易于理解和维护的代码。本文将介绍Lambda表达式和Stream API的基本概念,并通过示例展示它们在实际项目中的应用。
探索Java中的Lambda表达式
【10月更文挑战第37天】本文将带你深入理解Java的Lambda表达式,从基础语法到高级特性,通过实例讲解其在函数式编程中的应用。我们还将探讨Lambda表达式如何简化代码、提高开发效率,并讨论其在实际项目中的应用。
|
并行计算 Java 编译器
深入理解Java中的Lambda表达式
在Java 8中引入的Lambda表达式,不仅简化了代码编写,还提升了代码可读性。本文将带你探索Lambda表达式背后的逻辑与原理,通过实例展示如何高效利用这一特性优化你的程序。
|
Java API 开发者
Java中的Lambda表达式:简洁代码的利器####
本文探讨了Java中Lambda表达式的概念、用途及其在简化代码和提高开发效率方面的显著作用。通过具体实例,展示了Lambda表达式如何在Java 8及更高版本中替代传统的匿名内部类,使代码更加简洁易读。文章还简要介绍了Lambda表达式的语法和常见用法,帮助开发者更好地理解和应用这一强大的工具。 ####
|
搜索推荐 Java API
探索Java中的Lambda表达式
本文将深入探讨Java 8引入的Lambda表达式,这一特性极大地简化了代码编写,提高了程序的可读性。通过实例分析,我们将了解Lambda表达式的基本概念、使用场景以及如何优雅地重构传统代码。文章不仅适合初学者,也能帮助有经验的开发者加深对Lambda表达式的理解。