我正在尝试使用Java lambda表达式计算迭代次数,但是会引发编译时错误:
Local variable count defined in an enclosing scope must be final or effectively final
public static void main(String[] args) {
List<String> names = new ArrayList<String>();
names.add("Ajeet");
names.add("Negan");
names.add("Aditya");
names.add("Steve");
int count = 0;
names.stream().forEach(s->
{
if(s.length()>6)
count++;
});
}
答案 0 :(得分:5)
您不能从Lambda的外部范围访问非final
变量。但是您不需要在这里,您可以根据自己的条件filter
stream
,count
。喜欢,
long count = names.stream().filter(s -> s.length() > 6).count();
答案 1 :(得分:4)
语句count++;
正在重新分配变量count
。
这在lambda表达式中是不允许的。在lambda中引用的局部变量必须是最终变量(或有效地是最终变量,这意味着它没有显式声明为最终变量,但是如果添加了final
则不会中断)
替代方法是使用原子整数:
AtomicInteger count = new AtomicInteger();
names.stream().forEach(s -> {
if (s.length() > 6)
count.incrementAndGet();
});
注意 ,仅当需要修改局部变量时,才应使用原子整数。如果所有这些只是为了计算count
变量,那么EliotFrish答案中的方法要好得多。
答案 2 :(得分:0)
此答案仅是为了提供更广泛的方法来克服此错误。
您可以定义自己的消费者,其计数:
NSInputStream
然后将这个新类的实例传递给使用者:
- (void)scheduleInRunLoop:(__unused NSRunLoop *)aRunLoop
forMode:(__unused NSString *)mode
{}
- (void)removeFromRunLoop:(__unused NSRunLoop *)aRunLoop
forMode:(__unused NSString *)mode
{}
最终让您在迭代后提取计数:
class CountingConsumer implements Consumer<String>{
int count;
public void accept(String s){
if(s.length() > 6){
count++;
}
}
}
但是更好的答案是使用普通的for循环:
CountingConsumer countingConsumer = new CountingConsumer();
names.forEach(countingConsumer);