当前位置: 首页 > 面试题库 >

从Lambda内部修改局部变量

尉迟正奇
2023-03-14
问题内容

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

正常

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

与Lambda

    int ordinal = 0;
    list.forEach(s -> {
        s.setOrdinal(ordinal);
        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]++);
});

使用 Java 10+

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

注意: 如果使用并行流, 非常小心。您可能无法获得预期的结果。诸如Stuart的其他解决方案可能更适合这些情况。

对于除 int

当然,这对于之外的其他类型仍然有效int。您只需要将包装类型更改为AtomicReference或该类型的数组即可。例如,如果您使用String,只需执行以下操作:

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

使用数组:

String[] value = { null };
list.forEach(s-> {
  value[0] = "blah";
});

或使用Java 10+:

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


 类似资料: