小编典典

从 lambda 内部修改局部变量

all

修改局部变量forEach会产生编译错误:

普通的

    int ordinal = 0;
    for (Example s : list) {
        s.setOrdinal(ordinal);
        ordinal++;
    }

使用 Lambda

    int ordinal = 0;
    list.forEach(s -> {
        s.setOrdinal(ordinal);
        ordinal++;
    });

知道如何解决这个问题吗?


阅读 93

收藏
2022-08-24

共1个答案

小编典典

使用包装器

任何一种包装都很好。

Java 10+ 中,使用这个结构,因为它很容易设置:

var wrapper = new Object(){ int ordinal = 0; };
list.forEach(s -> {
  s.setOrdinal(wrapper.ordinal++);
});

Java 8+
中,使用以下任一AtomicInteger

AtomicInteger ordinal = new AtomicInteger(0);
list.forEach(s -> {
  s.setOrdinal(ordinal.getAndIncrement());
});

…或一个数组:

int[] ordinal = { 0 };
list.forEach(s -> {
  s.setOrdinal(ordinal[0]++);
});

注意: 如果您使用并行流,请务必小心。您可能不会得到预期的结果。像Stuart
其他解决方案可能更适合这些情况。

对于除int

当然,这对于除int.

例如,对于 Java 10+

var wrapper = new Object(){ String value = ""; };
list.forEach(s->{
  wrapper.value += "blah";
});

或者,如果您对 Java 89
感到困惑,请使用与我们在上面所做的相同类型的构造,但使用AtomicReference

AtomicReference<String> value = new AtomicReference<>("");
list.forEach(s -> {
  value.set(value.get() + s);
});

…或一个数组:

String[] value = { "" };
list.forEach(s-> {
  value[0] += s;
});
2022-08-24