Java lambda 表达式

本文详细介绍了Java中的Lambda表达式,包括其语法、函数式接口的概念、方法引用的使用以及构造器引用的简介。Lambda表达式支持简洁的语法来表示匿名函数,它可以捕获final或effectivelyfinal的变量。函数式接口则为Lambda表达式提供了目标类型。方法引用作为Lambda的替代形式,简化了代码。文章还提到了构造器引用的初步概念。
摘要由CSDN通过智能技术生成

1、lambda 表达式的语法

参数、箭头和表达式:

Arrays.sort(strs, (String s1, String s2) -> s1.length() - s2.length());

如果代码的计算无法放在一个表达式中,则可以放在{}中:

Arrays.sort(strs, (String s1, String s2) -> {
    return s1.length() - s2.length();
});

如果可以推导出参数类型,则可以忽略其类型:

Comparator<String> comp = (s1, s2) -> s1.length() - s2.length();

即使没有参数,仍需要提供空括号:

() -> { for(int i = 100; i >= 0; i--) System.out.println(i); }

如果只有一个参数,并且可以推导出类型,这时可以省略小括号:

ActionListener listener = event -> System.out.println("...");

补充:

  • lambda 表达式是延迟执行
  • lambda 表达式可以捕获外围方法或类中的final变量事实最终变量(effectively final)
  • lambda 表达式的体与嵌套块有相同的作用域,在表达式中声明与局部变量同名的参数或局部变量是不合法的

解释一下第二点,事实最终变量,即初始化后不会再赋新值的变量,如下代码中变量 s 就是事实最终变量。

public class Main {
    public static void main(String[] args) {
        String s = "Hello World!";
        String[] strs = {"Light", "Zero", "Alex"};
        Arrays.sort(strs, (String s1, String s2) -> {
            System.out.println(s);
            return s1.length() - s2.length();
        });
        System.out.println(Arrays.toString(strs));
    }
}

如果我们在定义变量 s 的语句后添加一个修改语句,lambda 表达式将会报错:

在这里插入图片描述

2、函数式接口

我们可以把 lambda 表达式赋值给函数式接口类型的对象(注意Object类型不是函数式接口类型)。

Java API 在java.util.function包中定义了很多通用的函数式接口,下面进行简单的介绍。(略)

3、方法引用

当 lambda 表达式只调用一个方法,而不做其他操作时,我们可以把 lambda 表达式重写为方法引用

例如,我们需要对字符串数组排序,而不考虑字母的大小写。

使用 lambda 表达式:

Arrays.sort(strs, (s1, s2) -> s1.compareToIgnoreCase(s2));

使用方法引用:

Arrays.sort(strs, String::compareToIgnoreCase);

表达式 String::compareToIgnoreCase 是一个方法引用,它指示编译器生成一个函数式接口的实例,覆盖这个接口的抽象方法来调用给定的方法。在这个例子中,会生成一个 Comparator 实例,它的 compare(T o1, T o2) 方法会调用 o1.compareToIgnoreCase(o2) 方法。

使用方法引用的情况主要有三种:

  • object::instanceMethod:方法引用等价于向方法传递参数的 lambda 表达式,如 System.out::println 等价于 x -> System.out.println(x)。
  • Class::instanceMethod:第一个参数会成为方法的隐式参数,如 String::compareToIgnoreCase 等价于 (x, y) -> x.compareToIgnoreCase(y)。
  • Class::staticMethod:所有的参数都传递到静态方法,如 Math::pow 等价于 (x, y) -> Math.pow(x, y)。

包含对象的方法引用与等价的 lamba 表达式的细微差别

String s = null;
Predicate<String> a = s::equals;
Predicate<String> b = x -> s.equals(x);

在这段代码中,构造方法引用时会立即抛出异常,而 lambda 表达式只在调用时抛出异常。

补充:可以在方法引用中使用thissuper,如 this::instanceMethod 或 super::instanceMethod。

4、构造器引用(待续)

使用方式为Class::new,如 int[]::new 或 String::new 等。(待补充举例)


如有错误,欢迎指正。.... .- ...- . .- -. .. -.-. . -.. .- -.-- -.-.--

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值