lambda expression中的值传递以及匹配返回

文章参考:
Variable used in lambda expression should be final or effectively final:https://www.cnblogs.com/zl0372/p/springBoot_error_3.html
Java Lambda表达式forEach无法跳出循环的解决思路:https://www.cnblogs.com/keeya/p/11306254.html

1、lambda表达式中的值传递

(1) Lambda与匿名内部类在访问外部变量时,都不允许有修改变量的倾向,即若:

final double a  = 3.141592;
double b = 3.141592;
 
DoubleUnaryOperator anotherDoubleUnaryOperator = x -> {
    a = 2; // ERROR
    b = 3; // ERROR
    return 0.0;
    };

则报错:Cannot assign a value to final variable,Variable used in lambda expression should be final or effectively final,无法改变final量的值,不允许在Lambda表达式中修改使用的(外部)变量。

(2) 由是观之,我们将Lambda的这种变量捕获行为称之为值捕获更加确切。
在实际操作中,如果我们在Lambda体内或匿名内部类中要对外部的某些量进行操作,那么这种限制也是很容易被规避,因为即使数组是final的(即该数组不能再指向其他数组对象),里面的值依旧可变。
所以我们只要将那个需要被操作的外部变量包装进一个数组即可:

final double[] a = {3.141592};
final double[] b = {3.141592};

DoubleUnaryOperator anotherDoubleUnaryOperator = x -> {
    a[0] = 2; // COOL
    b[0] = 3; // ALSO COOL
    return 0.0;
};

2、lambda expression如何终止循环的问题

(1) 如果你使用过forEach方法来遍历集合,你会发现在lambda表达式中的return并不会终止循环,这是由于lambda的底层实现导致的,看下面的例子:

public static void main(String[] args) {
    List<String> list = Lists.newArrayList();
    list.add("a");
    list.add("b");
    list.add("c");
    list.forEach(s -> {
        System.out.println("s = " + s);
        if (s.equals("b")) {
            return;
        }
    });
}
//返回结果:
//s = a
//s = b
//s = c

(2) 可以看到在forEach方法中即是采用了return,循环却仍在继续,那有什么办法能跳出循环呢?
使用anyMatch()函数,里接收一个返回值为boolean类型的表达式,只要返回true就会终止循环,这样可以将业务逻辑写在返回判断结果前。

public static void main(String[] args) {
    List<String> list = Lists.newArrayList();
    list.add("a");
    list.add("b");
    list.add("c");

    list.stream().anyMatch(s -> {
        System.out.println("do something");
        System.out.println("s=" + s);
        return s.equals("b");
    });
}
// do something
// s=a
// do something
// s=b

同理,采用类似的思路可以使用filter()方法,思路是一样的,其中findAny表示只要找到满足的条件时停止。

public static void main(String[] args) {
    List<String> list = Lists.newArrayList();
    list.add("a");
    list.add("b");
    list.add("c");

    list.stream().filter(s -> {
        System.out.println("s=" + s);
        return s.equals("b");
    }).findAny();
}
//返回结果:
//s = a
//s = b
©️2020 CSDN 皮肤主题: 精致技术 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值