ArrayList的subList使用过程中的注意事项

本文详细探讨了Java中List接口的subList()方法,它用于创建集合的一个视图,而非副本。当对原集合或子集合进行修改时,两者会互相影响,可能导致并发修改异常。通过示例代码展示了子集合的增删改查操作,并分析了可能出现的问题和源码解析,揭示了subList()内部的工作原理。
摘要由CSDN通过智能技术生成

subList()是返回集合在区间[startIndex, endIndex)的元素集合

public static final void main(String[] args) {

        List<String> stringList = new ArrayList(){{
            add("test0");
            add("test1");
            add("test2");
            add("test3");
            add("test4");
        }};

        List<String> subList = stringList.subList(2,4); //[startIndex, endIndex)
        System.out.println("stringList=>" + stringList);
        System.out.println("subList=>" + subList);
    }

输出结果
在这里插入图片描述
注意事项❗️

  1. 删除、新增原集合元素,在遍历、增加、删除子集合元素时会报系统异常ConcurrentModificationException
		// 省略前置代码
        System.out.println("原集合添加test5");
        try {
            stringList.add("test5"); // 不会报错
            // stringList.remove("test2")
            System.out.println(subList); // 输出subList时抛出ConcurrentModificationException异常

        } catch (Exception exception) {
            exception.printStackTrace();
        }

在这里插入图片描述

  1. 修改原集合的元素,子元素的集合也会改变
		List<String> subList = stringList.subList(2,4); //[startIndex, endIndex)
        System.out.println("修改原集合元素");
        try {
            stringList.set(3, "update->test0");
            System.out.println("subList => " + subList);

        } catch (Exception exception) {
            exception.printStackTrace();
        }

在这里插入图片描述

  1. 修改子集合的元素,会导致原集合发生改变
		List<String> subList = stringList.subList(2,4); //[startIndex, endIndex)
        System.out.println("修改子集合元素");
        try {
            subList.set(0, "updateSub->test2");
            System.out.println("stringList => " + stringList);
            System.out.println("subList => " + subList);

        } catch (Exception exception) {
            exception.printStackTrace();
        }

在这里插入图片描述

  1. 子集合添加或删除元素,原集合也会发生变化。
List<String> subList = stringList.subList(2,4); //[startIndex, endIndex)
        System.out.println("子集合添加/删除元素");
        try {
            subList.add("subAdd");
            // subList.remove(0);
            System.out.println("stringList => " + stringList);
            System.out.println("subList => " + subList);

        } catch (Exception exception) {
            exception.printStackTrace();
        }

在这里插入图片描述
在这里插入图片描述
原因🔍
查看subList()源码

public List<E> subList(int fromIndex, int toIndex) {
        return new SubList<>(this, fromIndex, toIndex);
    }
SubList(AbstractList<E> list, int fromIndex, int toIndex) {
        if (fromIndex < 0)
            throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
        if (toIndex > list.size())
            throw new IndexOutOfBoundsException("toIndex = " + toIndex);
        if (fromIndex > toIndex)
            throw new IllegalArgumentException("fromIndex(" + fromIndex +
                                               ") > toIndex(" + toIndex + ")");
        l = list;
        offset = fromIndex;
        size = toIndex - fromIndex;
        this.modCount = l.modCount;
    }

发现new SubList<>(this, fromIndex, toIndex)构造函数并没有返回一个新的集合对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

又菜又爱哭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值