局部变量出错+;Java中的lambda函数

局部变量出错+;Java中的lambda函数,java,variables,lambda,syntax-error,local,Java,Variables,Lambda,Syntax Error,Local,我遇到了一个关于局部变量和lambdafunction的奇怪问题,它似乎无法处理这个问题。我不断收到错误消息“在封闭范围内定义的局部变量acc必须是final或有效final” 我的代码如下所示: Accumulator acc = new Accumulator(0, 0); stream.reduce(0, (sum, value) -> { acc = new Accumulator(sum + value, acc.getB()+1); return sum + v

我遇到了一个关于局部变量和lambdafunction的奇怪问题,它似乎无法处理这个问题。我不断收到错误消息“在封闭范围内定义的局部变量acc必须是final或有效final”

我的代码如下所示:

Accumulator acc = new Accumulator(0, 0);
stream.reduce(0, (sum, value) -> {
    acc = new Accumulator(sum + value, acc.getB()+1);
    return sum + value;
});
如你所见,我试图减少一个整数流,并保留2个值,而不仅仅是减少过程中的一个值。我试图将这些值保存在小助手类
累加器中,该类获得了一个
最终int a
和一个
最终int b
来存储这些值。但是,它看起来像是流。reduce
无法到达
acc

在我的程序的其他部分,包括其他lambda函数,类似的代码结构工作得很好(声明局部变量并在lambda函数中更改它们),所以我不知道该怎么做

示例(当然,
已初始化):

ArrayList studentList=new ArrayList();
stream.forEach(学生->{
学生列表。添加(学生);
});
我们将不胜感激,
关于

变量不能声明为final,但不能重新赋值,因此它实际上是final。 在代码的第3行中,重新分配变量。这是不可能的


如果您说,您已经在其他代码中成功地完成了类似的事情:我认为这是不可能的。您可能更改了变量所引用的对象,但没有更改变量本身。

如注释中所述,您不能在lambda表达式中指定局部变量。但是,有一些方法可以调用
reduce
方法来生成所需的输出

例如:

Stream<Integer> stream = Stream.of (1,2,3,4,5);
Accumulator result =
    stream.reduce(new Accumulator(0,0), // initial value
                  (acc, i) -> {acc.a += i;acc.b++; return acc;}, // add current value to
                                                                 // the accumulator
                  (acc1, acc2) -> new Accumulator (acc1.a+acc2.a,acc1.b+acc2.b)); // combine two accumulators
System.out.println ("sum = " + result.a);
System.out.println ("count = " + result.b);

我想这只是为了教育目的。如果不是,则使用
IntStream
summaryStatistics()
来计算总和、元素数和其他属性(最小值、最大值和平均值)。

错误消息会准确地告诉您出了什么问题:
acc
未声明
final
。问题是什么?更多关于搜索。如果你也发布其他代码,那么我们可以告诉你区别是什么。问题是,每当
reduce
计算新的
sum
时,我需要重新实例化
acc
,这在声明为final后是不可能的。正如我所说的,我在没有声明变量
final
的情况下成功地获得了几个类似的代码结构,不要试图在注释中给出代码。请回答您的问题并在其中添加所有需要的信息。谢谢,就这样。我不完全确定“有效最终”是什么意思。虽然您的答案可能是正确的,但在不参考java规范或文档的情况下提出这种声明是不可取的,因为您描述的是规范的细节,将来可能会发生变化。否则,请包括您正在使用的当前java版本,其中您观察到了这种行为。或者首先确保你的主张在不同的例子中是正确的,并将它们包括在答案中。就我个人而言,我知道下一个java版本计划对其进行更改,因此这个答案会让未来的访问者感到困惑。@希望有帮助,因为这个问题使用了lamdas,我们当然是在谈论java 8。事实上,在Java8之前,匿名内部类只能使用显式声明为final的变量(Java7或Java7之前没有“有效final”的概念)。是的,这是出于教育目的,我们甚至没有被要求在流程中使用类似于累加器的类。我只是想实现它,陷入困境,想知道为什么。谢谢你的片段,它帮了我很大的忙!
Stream<Integer> stream = Stream.of (1,2,3,4,5);
Accumulator result =
    stream.reduce(new Accumulator(0,0), // initial value
                  (acc, i) -> {acc.a += i;acc.b++; return acc;}, // add current value to
                                                                 // the accumulator
                  (acc1, acc2) -> new Accumulator (acc1.a+acc2.a,acc1.b+acc2.b)); // combine two accumulators
System.out.println ("sum = " + result.a);
System.out.println ("count = " + result.b);
sum = 15
count = 5