Java 中的局部变量 + lambda 函数出错
Error with local variable + lambda-function in Java
我遇到了一个关于局部变量和 lambda 函数的奇怪问题,似乎无法处理它。我不断收到错误消息 "local variable acc defined in an enclosing scope must be final or effectively final"
我的代码如下所示:
Accumulator acc = new Accumulator(0, 0);
stream.reduce(0, (sum, value) -> {
acc = new Accumulator(sum + value, acc.getB()+1);
return sum + value;
});
如您所见,我正在尝试减少整数流并保留 2 个值,而不仅仅是减少过程中的那个值。我试图将这些值保存在小助手 class Accumulator
中,它有一个 final int a
和一个 final int b
来存储这些值。但是,似乎 stream.reduce
无法到达 acc
。
在我程序的其他部分,包括其他 lambda 函数,类似的代码结构工作正常(声明局部变量并在 lambda 函数内更改它们),所以我不知道该怎么做。
例子(stream
当然是初始化的):
ArrayList<StudentRecord> studentList = new ArrayList<StudentRecord>();
stream.forEach(student -> {
studentList.add(student);
});
不胜感激,
此致
变量不得声明为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);
这只会产生一个 Accumulator
实例(除非您的 Stream
是并行的)。输出 Accumulator
将包含 acc.a
中的总和和 acc.b
中的元素数。
输出:
sum = 15
count = 5
我假设这仅用于教育目的。如果不是,使用 IntStream
的 summaryStatistics()
计算总和、元素数量和其他属性(最小值、最大值和平均值)会更有意义。
我遇到了一个关于局部变量和 lambda 函数的奇怪问题,似乎无法处理它。我不断收到错误消息 "local variable acc defined in an enclosing scope must be final or effectively final"
我的代码如下所示:
Accumulator acc = new Accumulator(0, 0);
stream.reduce(0, (sum, value) -> {
acc = new Accumulator(sum + value, acc.getB()+1);
return sum + value;
});
如您所见,我正在尝试减少整数流并保留 2 个值,而不仅仅是减少过程中的那个值。我试图将这些值保存在小助手 class Accumulator
中,它有一个 final int a
和一个 final int b
来存储这些值。但是,似乎 stream.reduce
无法到达 acc
。
在我程序的其他部分,包括其他 lambda 函数,类似的代码结构工作正常(声明局部变量并在 lambda 函数内更改它们),所以我不知道该怎么做。
例子(stream
当然是初始化的):
ArrayList<StudentRecord> studentList = new ArrayList<StudentRecord>();
stream.forEach(student -> {
studentList.add(student);
});
不胜感激, 此致
变量不得声明为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);
这只会产生一个 Accumulator
实例(除非您的 Stream
是并行的)。输出 Accumulator
将包含 acc.a
中的总和和 acc.b
中的元素数。
输出:
sum = 15
count = 5
我假设这仅用于教育目的。如果不是,使用 IntStream
的 summaryStatistics()
计算总和、元素数量和其他属性(最小值、最大值和平均值)会更有意义。