You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义ArrayList如何实现与原列表联动的subList()方法

问题原因分析

你现在的实现之所以修改子列表无法同步到原列表,核心原因是你主动复制了原数组的元素到新数组,再用新数组生成独立List,新List和原列表没有绑定关系,修改操作只会作用于新数组,自然不会影响原列表。

解决方案

你确实需要额外实现一个内部的SubList类,这个类不单独存储数据,所有操作都直接代理到原列表实现,就能实现修改同步。

步骤1:在CustomArrayList内部实现SubList内部类

推荐继承AbstractList减少需要实现的方法量,示例代码如下:

public class CustomArrayList<T> {
    // 你原有的其他成员变量
    private Object[] array;
    private int size;
    // 可选:和JDK实现对齐,新增modCount记录列表结构修改次数,避免并发修改问题
    private int modCount = 0;

    private class SubList extends AbstractList<T> {
        private final CustomArrayList<T> parent;
        private final int offset;
        private int subSize;
        // 记录生成子列表时原列表的modCount,结构变更后操作子列表直接抛异常
        private final int expectedModCount;

        SubList(CustomArrayList<T> parent, int fromIndex, int toIndex) {
            this.parent = parent;
            this.offset = fromIndex;
            this.subSize = toIndex - fromIndex;
            this.expectedModCount = parent.modCount;
        }

        @Override
        public T get(int index) {
            // 校验子列表索引合法性
            if (index < 0 || index >= subSize) {
                throw new IndexOutOfBoundsException();
            }
            // 校验原列表结构是否发生变化
            checkForComodification();
            // 直接取原列表对应偏移位置的元素
            return parent.get(offset + index);
        }

        @Override
        public T set(int index, T element) {
            if (index < 0 || index >= subSize) {
                throw new IndexOutOfBoundsException();
            }
            checkForComodification();
            // 直接修改原列表对应位置的元素
            return parent.set(offset + index, element);
        }

        @Override
        public int size() {
            checkForComodification();
            return subSize;
        }

        @Override
        public void add(int index, T element) {
            if (index < 0 || index > subSize) {
                throw new IndexOutOfBoundsException();
            }
            checkForComodification();
            parent.add(offset + index, element);
            // 原列表结构变更,更新modCount和子列表长度
            expectedModCount = parent.modCount;
            subSize++;
        }

        @Override
        public T remove(int index) {
            if (index < 0 || index >= subSize) {
                throw new IndexOutOfBoundsException();
            }
            checkForComodification();
            T removed = parent.remove(offset + index);
            expectedModCount = parent.modCount;
            subSize--;
            return removed;
        }

        private void checkForComodification() {
            if (parent.modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
        }
    }
    // 你原有的其他方法,注意在add/remove等修改结构的方法里modCount自增
}

注意:你原有的add、remove等会修改列表结构的方法,需要每次执行时对modCount执行自增操作,和JDK的ArrayList实现逻辑对齐。

步骤2:修改subList方法实现

删掉原来复制数组的逻辑,直接返回SubList实例即可:

public List<T> subList(int fromIndex, int toIndex) {
    if (fromIndex < 0 || toIndex > size() || fromIndex > toIndex)
        throw new IndexOutOfBoundsException();
    return new SubList(this, fromIndex, toIndex);
}

修改完成后运行你的测试用例,调用subList(1,4).set(0,12)时,会直接修改原列表索引1+0=1位置的元素,即可通过测试。

内容的提问来源于stack exchange,提问作者alqueen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 12:39:03