从 lambda 内部修改局部变量 [英] Modifying local variable from inside lambda

查看:15
本文介绍了从 lambda 内部修改局部变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

forEach 中修改局部变量会导致编译错误:

Modifying a local variable in forEach gives a compile error:

正常

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

使用 Lambda

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

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

Any idea how to resolve this?

推荐答案

使用包装器

任何类型的包装都很好.

Use a wrapper

Any kind of wrapper is good.

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

With Java 10+, use this construct as it's very easy to setup:

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

对于 Java 8+,使用 AtomicInteger:

With Java 8+, use either an AtomicInteger:

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

... 或一个数组:

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

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

Note: be very careful if you use a parallel stream. You might not end up with the expected result. Other solutions like Stuart's might be more adapted for those cases.

当然,这对 int 以外的类型仍然有效.

Of course, this is still valid for types other than int.

例如,使用 Java 10+:

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

或者,如果您坚持使用 Java 89,请使用与我们上面所做的相同类型的构造,但使用 AtomicReference...

Or if you're stuck with Java 8 or 9, use the same kind of construct as we did above, but with an AtomicReference...

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

... 或一个数组:

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

这篇关于从 lambda 内部修改局部变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆