繁体   English   中英

如何从Java 8中的lambda表达式中获取信息?

[英]How do I get information out of a lambda expression in Java 8?

我理解为什么lambda表达式不能改变局部变量,我理解他们可以访问和mututae类字段。 对我来说,lambdas在许多情况下创建了更具表现力的代码,我想更频繁地使用它们。

我的问题是使用l​​ambda的最佳实践不是单方法对象替换,而是简化代码如下:

int pairsFound = 0;
for (Map.Entry<String, Integer> entry : counters.entrySet())
    {
        if (entry.getValue() == 2)
            pairsFound++;
    }

pairsFound = map.forEach((key, value) ->
{
    int z = 0;
    if (value == 2)
        z++;
    return z;
});

要么

map.forEach((key, value) ->
{
    if (value == 2)
        pairsFound++;
});

一种解决方案是使parisFound成为实例字段。 但是,对于从未在单一方法之外使用过的变量进行实例化,对我来说似乎是一种代码味道。 此外,如果封闭类是静态的(例如在测试运行中),这将不起作用。

有没有其他方法可以从一个lambda中获取信息,而这种方式的安全性并不比使用每个循环更安全? 我理解lambda可能存在并发问题,但在我的大多数简化用例中,我不知道lambda是否会比它替换的更安全。

这种情况最简单的方法是创建一个流,在entry.getValue() == 2的条件下过滤,然后count()结果。 像这样的东西:

long pairsFound = map.values().stream().filter(v -> v == 2).count(); //using values() rather than entrySet() makes the code more readable

一般的教训是,使用lambdas需要一种不同的思维模式,一种更接近函数式编程(lambdas的概念起源于此),而不是试图在其上强加相同的命令式原则。 从lambda中获取信息的正确方法是评估它们,而不是通过副作用。

要与当前实现保持一致,您需要使用map而不是forEach来返回值,然后使用reduce来累积:

pairsFound = map.values().stream()
       .map(value -> value == 2 ? 1 : 0)
       .reduce(Integer::sum);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM