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;
}
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.
There is a
count
method in stream to do counts for you.If you want parallelisation, change
.stream()
to.parallelStream()
.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.To get both numbers, matching and non-matching elements, you can use
But since your source is a
Map
, which knows its total size, and want to calculate a percentage, for whichbarCount
is not needed, this specific task can be solved asBoth variants are thread safe, i.e. changing
stream()
toparallelStream()
will perform the operation in parallel, however, it’s unlikely that this operation will benefit from parallel processing. You would need humongous key strings or maps to get a benefit…I agree with the other answers indicating you should use
count
orpartitioningBy
.Just to explain the atomicity problem with an example, consider the following code:
This returns the expected result of 100000 for
i1
but an indeterminate number less than that (between 50000 and 80000 in my test runs) fori2
. The reason should be pretty obvious.