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

如何创建ArrayList的不可变子类?ColorList实现技术咨询

改造ColorList为ArrayList的不可变子类方案

嘿,我来帮你搞定这个不可变ColorList的改造问题!要把继承自ArrayList<Color>的类改成不可变的,核心就是阻止任何外部对列表元素的修改操作,同时保留你需要的循环获取颜色的功能。下面是具体的改造步骤和完整代码:

核心改造思路

因为ArrayList本身是可变集合,继承它的子类默认会继承所有修改方法(比如add、remove、clear),所以我们需要:

  1. 重写所有能修改集合的方法,让它们抛出UnsupportedOperationException(Java标准不可变集合的统一做法)
  2. 确保实例初始化后,内部元素无法被修改
  3. 保留你需要的循环获取颜色的逻辑,同时保证线程安全(可选,根据你的使用场景调整)

完整改造代码

import java.awt.Color;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

@SuppressWarnings("serial")
public final class ColorList extends ArrayList<Color> {
    private static int colorIndex = -1;
    // 初始化固定的颜色集合
    private static final Color[] FIXED_COLORS = {
        Color.CYAN, Color.DARK_GRAY, Color.GRAY,
        Color.GREEN, Color.BLUE, Color.LIGHT_GRAY
    };

    public ColorList() {
        // 一次性初始化所有颜色,后续不再允许修改
        super(FIXED_COLORS.length);
        for (Color color : FIXED_COLORS) {
            super.add(color);
        }
    }

    // 实现循环获取颜色的核心方法
    public synchronized Color getNextColor() {
        colorIndex = (colorIndex + 1) % this.size();
        return this.get(colorIndex);
    }

    // --------------------------
    // 重写所有修改方法,抛出不可修改异常
    // --------------------------
    @Override
    public boolean add(Color e) {
        throw new UnsupportedOperationException("ColorList is immutable");
    }

    @Override
    public void add(int index, Color element) {
        throw new UnsupportedOperationException("ColorList is immutable");
    }

    @Override
    public boolean addAll(java.util.Collection<? extends Color> c) {
        throw new UnsupportedOperationException("ColorList is immutable");
    }

    @Override
    public boolean addAll(int index, java.util.Collection<? extends Color> c) {
        throw new UnsupportedOperationException("ColorList is immutable");
    }

    @Override
    public void clear() {
        throw new UnsupportedOperationException("ColorList is immutable");
    }

    @Override
    public Color remove(int index) {
        throw new UnsupportedOperationException("ColorList is immutable");
    }

    @Override
    public boolean remove(Object o) {
        throw new UnsupportedOperationException("ColorList is immutable");
    }

    @Override
    public boolean removeAll(java.util.Collection<?> c) {
        throw new UnsupportedOperationException("ColorList is immutable");
    }

    @Override
    public boolean retainAll(java.util.Collection<?> c) {
        throw new UnsupportedOperationException("ColorList is immutable");
    }

    @Override
    public Color set(int index, Color element) {
        throw new UnsupportedOperationException("ColorList is immutable");
    }

    @Override
    public void replaceAll(java.util.function.UnaryOperator<Color> operator) {
        throw new UnsupportedOperationException("ColorList is immutable");
    }

    @Override
    public void sort(java.util.Comparator<? super Color> c) {
        throw new UnsupportedOperationException("ColorList is immutable");
    }

    // --------------------------
    // 重写迭代器,防止通过迭代器修改元素
    // --------------------------
    @Override
    public Iterator<Color> iterator() {
        return new ImmutableIterator(super.iterator());
    }

    @Override
    public ListIterator<Color> listIterator() {
        return new ImmutableListIterator(super.listIterator());
    }

    @Override
    public ListIterator<Color> listIterator(int index) {
        return new ImmutableListIterator(super.listIterator(index));
    }

    // 不可变迭代器实现
    private static class ImmutableIterator implements Iterator<Color> {
        private final Iterator<Color> delegate;

        public ImmutableIterator(Iterator<Color> delegate) {
            this.delegate = delegate;
        }

        @Override
        public boolean hasNext() {
            return delegate.hasNext();
        }

        @Override
        public Color next() {
            return delegate.next();
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("ColorList is immutable");
        }
    }

    // 不可变列表迭代器实现
    private static class ImmutableListIterator implements ListIterator<Color> {
        private final ListIterator<Color> delegate;

        public ImmutableListIterator(ListIterator<Color> delegate) {
            this.delegate = delegate;
        }

        @Override
        public boolean hasNext() {
            return delegate.hasNext();
        }

        @Override
        public Color next() {
            return delegate.next();
        }

        @Override
        public boolean hasPrevious() {
            return delegate.hasPrevious();
        }

        @Override
        public Color previous() {
            return delegate.previous();
        }

        @Override
        public int nextIndex() {
            return delegate.nextIndex();
        }

        @Override
        public int previousIndex() {
            return delegate.previousIndex();
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("ColorList is immutable");
        }

        @Override
        public void set(Color e) {
            throw new UnsupportedOperationException("ColorList is immutable");
        }

        @Override
        public void add(Color e) {
            throw new UnsupportedOperationException("ColorList is immutable");
        }
    }
}

关键细节说明

  1. 初始化优化:把固定颜色放到一个静态数组里,构造方法里一次性添加到父类ArrayList中,避免后续修改。
  2. 线程安全的循环逻辑:给getNextColor()加上synchronized关键字(如果你的应用是多线程场景的话),防止多个线程同时修改colorIndex导致顺序混乱。如果是单线程场景,可以去掉synchronized。
  3. 覆盖所有修改入口:不仅要覆盖add、remove这些直接修改方法,还要覆盖迭代器的修改方法,因为外部可能通过迭代器来修改集合元素。
  4. final类:保持类为final,防止子类重写我们的不可变逻辑。

补充建议(可选)

其实Java官方更推荐组合而非继承来实现不可变集合,因为继承ArrayList需要覆盖大量方法,容易遗漏。如果可以不继承ArrayList,你可以这样实现:

import java.awt.Color;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public final class ColorList {
    private static int colorIndex = -1;
    private final List<Color> immutableColors;

    public ColorList() {
        List<Color> tempList = new ArrayList<>();
        tempList.add(Color.CYAN);
        tempList.add(Color.DARK_GRAY);
        tempList.add(Color.GRAY);
        tempList.add(Color.GREEN);
        tempList.add(Color.BLUE);
        tempList.add(Color.LIGHT_GRAY);
        immutableColors = Collections.unmodifiableList(tempList);
    }

    public synchronized Color getNextColor() {
        colorIndex = (colorIndex + 1) % immutableColors.size();
        return immutableColors.get(colorIndex);
    }

    // 暴露需要的只读方法,比如get、size等
    public Color get(int index) {
        return immutableColors.get(index);
    }

    public int size() {
        return immutableColors.size();
    }
}

这种方式更简洁,而且天然不可变,不需要自己覆盖一堆方法。不过如果你的场景必须继承ArrayList,那还是用第一种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:31:27