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);

总结

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

目录
相关文章
|
1月前
|
Java API 开发者
Java中的Lambda表达式与Stream API的协同作用
在本文中,我们将探讨Java 8引入的Lambda表达式和Stream API如何改变我们处理集合和数组的方式。Lambda表达式提供了一种简洁的方法来表达代码块,而Stream API则允许我们对数据流进行高级操作,如过滤、映射和归约。通过结合使用这两种技术,我们可以以声明式的方式编写更简洁、更易于理解和维护的代码。本文将介绍Lambda表达式和Stream API的基本概念,并通过示例展示它们在实际项目中的应用。
|
2月前
|
Java API 开发者
Java中的Lambda表达式:简洁代码的利器####
本文探讨了Java中Lambda表达式的概念、用途及其在简化代码和提高开发效率方面的显著作用。通过具体实例,展示了Lambda表达式如何在Java 8及更高版本中替代传统的匿名内部类,使代码更加简洁易读。文章还简要介绍了Lambda表达式的语法和常见用法,帮助开发者更好地理解和应用这一强大的工具。 ####
|
2月前
|
并行计算 Java 编译器
深入理解Java中的Lambda表达式
在Java 8中引入的Lambda表达式,不仅简化了代码编写,还提升了代码可读性。本文将带你探索Lambda表达式背后的逻辑与原理,通过实例展示如何高效利用这一特性优化你的程序。
|
2月前
|
搜索推荐 Java API
探索Java中的Lambda表达式
本文将深入探讨Java 8引入的Lambda表达式,这一特性极大地简化了代码编写,提高了程序的可读性。通过实例分析,我们将了解Lambda表达式的基本概念、使用场景以及如何优雅地重构传统代码。文章不仅适合初学者,也能帮助有经验的开发者加深对Lambda表达式的理解。
|
2月前
|
Java
探索Java中的Lambda表达式
【10月更文挑战第37天】本文将带你深入理解Java的Lambda表达式,从基础语法到高级特性,通过实例讲解其在函数式编程中的应用。我们还将探讨Lambda表达式如何简化代码、提高开发效率,并讨论其在实际项目中的应用。
|
2月前
|
Java API
Java中的Lambda表达式与函数式编程####
【10月更文挑战第29天】 本文将深入探讨Java中Lambda表达式的实现及其在函数式编程中的应用。通过对比传统方法,我们将揭示Lambda如何简化代码、提高可读性和维护性。文章还将展示一些实际案例,帮助读者更好地理解和应用Lambda表达式。 ####
|
2月前
|
Java API 开发者
Java中的Lambda表达式与函数式编程####
在Java的演变过程中,Lambda表达式和函数式编程的引入无疑是一次重大的飞跃。本文将深入探讨Lambda表达式的定义、用法及优势,并结合实例说明如何在Java中利用Lambda表达式进行函数式编程。通过对比传统编程方式,揭示Lambda表达式如何简化代码、提高开发效率和可维护性。 ####
|
1月前
|
安全 Java API
Java中的Lambda表达式:简化代码的现代魔法
在Java 8的发布中,Lambda表达式的引入无疑是一场编程范式的革命。它不仅让代码变得更加简洁,还使得函数式编程在Java中成为可能。本文将深入探讨Lambda表达式如何改变我们编写和维护Java代码的方式,以及它是如何提升我们编码效率的。
|
2月前
|
安全 Java API
Java中的Lambda表达式与Stream API的高效结合####
探索Java编程中Lambda表达式与Stream API如何携手并进,提升数据处理效率,实现代码简洁性与功能性的双重飞跃。 ####
29 0
|
2月前
|
Java API 数据处理
探索Java中的Lambda表达式与Stream API
【10月更文挑战第22天】 在Java编程中,Lambda表达式和Stream API是两个强大的功能,它们极大地简化了代码的编写和提高了开发效率。本文将深入探讨这两个概念的基本用法、优势以及在实际项目中的应用案例,帮助读者更好地理解和运用这些现代Java特性。