Java 8 Lambda问题在递增计数时有效最终

Java 8 Lambda问题在递增计数时有效最终

问题描述:

我想在以下场景中使用Java 8 Lambda表达式,但我得到在封闭范围内定义的局部变量fooCount必须是最终的或有效的最终。我理解错误信息的内容,但我需要在这里计算百分比,所以需要增加 fooCount barCount 然后计算百分比。那么实现它的方法是什么:

I want to use Java 8 Lambda expression in following scenario but I am getting Local variable fooCount defined in an enclosing scope must be final or effectively final. I understand what the error message says, but I need to calculate percentage here so need to increment fooCount and barCount then calculate percentage. So what's the way to achieve it:

        // key is a String with values like "FOO;SomethinElse" and value is Long
        final Map<String, Long> map = null;
    ....
    private int calculateFooPercentage() {
        long fooCount = 0L;
        long barCount = 0L;

        map.forEach((k, v) -> {
            if (k.contains("FOO")) {
                fooCount++;
            } else {
                barCount++;
            }
        });

        final int fooPercentage = 0;
        //Rest of the logic to calculate percentage
        ....
        return fooPercentage;
    }

我有一个选项是使用 AtomicLong 这里而不是 long 但是我想避免它,所以稍后如果可能的话我想在这里使用并行流。

One option I have is to use AtomicLong here instead of long but I would like to avoid it, so later if possible I want to use parallel stream here.

有一个 count 方法为你做计数。

There is a count method in stream to do counts for you.

long fooCount = map.keySet().stream().filter(k -> k.contains("FOO")).count();
long barCount = map.size() - fooCount;

如果要进行并行化,请更改 .stream() .parallelStream( )

If you want parallelisation, change .stream() to .parallelStream().

或者,如果您尝试手动增加变量,并使用流并行化,那么您可能希望使用像 AtomicLong 之类的东西来获得线程安全性。即使编译器允许,一个简单的变量也不是线程安全的。

Alternatively, if you were trying to increment a variable manually, and use stream parallelisation, then you would want to use something like AtomicLong for thread safety. A simple variable, even if the compiler allowed it, would not be thread-safe.