java8 list.forEach() 修改值失败

本文探讨了Java中对于ArrayList的遍历修改问题,通过测试代码展示了基础类型和对象类型的差异。在遍历ArrayList时,直接修改元素会导致ConcurrentModificationException,而对象引用的修改则不会抛出异常,这是因为基础类型是值传递,对象则是引用传递。理解这一区别对于避免并发修改异常至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

测试代码

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    private String name;

    public static void main(String[] args) {
        List<User> list = new ArrayList<>();
        list.add(new User("bb"));
        list.forEach(u -> {
            u.setName("aaa");
        });
        System.out.println(list);

        List<String> list2 = new ArrayList<>();
        list2.add("bb");
        list2.forEach(u -> {
            u = "aaa";
        });
        System.out.println(list2);

        List<String[]> list3 = new ArrayList<>();
        list3.forEach(arr -> {
            arr = new String[]{"aaa"};
        });
        System.out.println(list3);
    }
}

结果

[User(name=aaa)]
[bb]
[]

原因

list.forEach掉的底层是ArrayList的forEach

@Override
    public void forEach(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        final int expectedModCount = modCount;
        @SuppressWarnings("unchecked")
        final E[] elementData = (E[]) this.elementData;
        final int size = this.size;
        for (int i=0; modCount == expectedModCount && i < size; i++) {
            action.accept(elementData[i]);
        }
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
    }

final E[] elementData = (E[]) this.elementData; 做了传参,然后把赋予的参数带到了action.accept(elementData[i]);中执行

如果是String、String[] 等基础类型,就会是值传递,导致后续的赋值失败
如果是引用对象类型,则传递得是引用,赋值会成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值