Reputation: 77
I have a little problem. When I write this for loop, the variable i
in f.getAnswerScore().get(i).... is underlined with error message : - Local variable i defined in an enclosing scope must be final or
effectively final. Does this have something to do with streams? Maybe streams can't be used in loops?
for (int i = 0; i < 10; i++) {
correct = active.stream()
.filter(f -> f.getAnswerScore().get(i).getStatus().equals(AnswerStatus.ANSWERED_CORRECT))
.count();
}
Upvotes: 3
Views: 8065
Reputation: 4587
rgettman's answer is a workaround. You never use correct
inside the loop, so why bother assigning to it 10 times rather than running it just once with i = 9
?
The answer is that you're probably doing something else with correct
that you're not showing us, and a thorough answer to the question would probably require us to know what that is. Because it's quite unlikely that a C-style for loop like you've written is actually the best/most elegant solution to the problem you're trying to solve.
One possibility is to collect all the correct
values in another stream:
IntStream.range(0, 10).map(i ->
active
.stream()
.filter(f ->
f.getAnswerScore()
.get(i)
.getStatus()
.equals(AnswerStatus.ANSWERED_CORRECT)
)
.count()
)
Of course, you might want to do something else entirely, there's no way for us to know.
Upvotes: 3
Reputation: 178263
Like anonymous inner classes, lambda expressions can only access local variables if they are final
or "effectively final" (Java 8 or higher; not final
but never changed once assigned).
This is covered by the JLS, Section 15.27.2:
Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared
final
or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.Any local variable used but not declared in a lambda body must be definitely assigned (§16 (Definite Assignment)) before the lambda body, or a compile-time error occurs.
Similar rules on variable use apply in the body of an inner class (§8.1.3). The restriction to effectively final variables prohibits access to dynamically-changing local variables, whose capture would likely introduce concurrency problems. Compared to the final restriction, it reduces the clerical burden on programmers.
Declare a final
variable equal to i
and use it.
for(int i = 0; i< 10; i++){
final int j = i;
correct = active
.stream()
.filter(f-> f.getAnswerScore().get(j).getStatus().equals(AnswerStatus.ANSWERED_CORRECT))
.count();
}
Upvotes: 7