基于 AbstractList 实现固定容量安全列表

核心设计思路
  1. 容量固定:初始化时指定容量,不可动态扩容
  2. 线程安全:所有修改操作使用 synchronized 同步
  3. 边界校验:所有操作进行索引边界检查
  4. 元素访问:支持安全的读写操作
Java 实现代码
import java.util.AbstractList;
import java.util.Arrays;
import java.util.Collection;

public class FixedCapacityList<E> extends AbstractList<E> {
    private final Object[] elements;  // 存储元素的数组
    private int size;                // 当前元素数量
    private final int capacity;      // 固定容量

    // 构造函数
    public FixedCapacityList(int capacity) {
        if (capacity < 0) 
            throw new IllegalArgumentException("容量不能为负数: " + capacity);
        this.capacity = capacity;
        this.elements = new Object[capacity];
        this.size = 0;
    }

    // 获取当前元素数量
    @Override
    public int size() {
        return size;
    }

    // 安全获取元素
    @Override
    @SuppressWarnings("unchecked")
    public E get(int index) {
        checkIndex(index);
        return (E) elements[index];
    }

    // 安全设置元素(替换)
    @Override
    @SuppressWarnings("unchecked")
    public synchronized E set(int index, E element) {
        checkIndex(index);
        E oldValue = (E) elements[index];
        elements[index] = element;
        return oldValue;
    }

    // 安全添加元素(尾部)
    @Override
    public synchronized boolean add(E element) {
        if (size == capacity) 
            throw new IllegalStateException("列表已满,容量: " + capacity);
        elements[size++] = element;
        return true;
    }

    // 安全删除元素
    @Override
    @SuppressWarnings("unchecked")
    public synchronized E remove(int index) {
        checkIndex(index);
        E removed = (E) elements[index];
        
        // 移动后续元素
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elements, index + 1, elements, index, numMoved);
        
        elements[--size] = null;  // 清除引用,防止内存泄漏
        return removed;
    }

    // 批量添加(安全)
    @Override
    public synchronized boolean addAll(Collection<? extends E> c) {
        int newElements = c.size();
        if (size + newElements > capacity)
            throw new IllegalStateException("超出容量限制: " + capacity);
        
        for (E element : c) {
            elements[size++] = element;
        }
        return newElements > 0;
    }

    // 索引边界检查
    private void checkIndex(int index) {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException("非法索引: " + index + ", 当前大小: " + size);
    }

    // 清空列表
    @Override
    public synchronized void clear() {
        Arrays.fill(elements, 0, size, null);
        size = 0;
    }
}

关键特性说明
  1. 容量限制

    • 初始化后容量固定,add() 操作在满容时抛出 IllegalStateException
    • 示例:new FixedCapacityList<String>(5) 创建最大容量为 5 的列表
  2. 线程安全机制

    public synchronized boolean add(E element) { ... }
    

    所有修改方法使用同步锁,确保多线程环境下的数据一致性

  3. 边界保护

    • checkIndex() 方法验证所有访问操作的合法性
    • 非法访问抛出 IndexOutOfBoundsException
  4. 内存管理

    elements[--size] = null;  // 清除对象引用
    

    删除元素时显式置空,避免内存泄漏

使用示例
FixedCapacityList<String> safeList = new FixedCapacityList<>(3);

safeList.add("A");  // 成功
safeList.add("B");  // 成功
safeList.add("C");  // 成功

System.out.println(safeList.get(1));  // 输出 "B"

safeList.add("D");  // 抛出 IllegalStateException(容量已满)

safeList.remove(0);  // 删除 "A"
safeList.add("D");  // 成功(现在有空位)

适用场景
  1. 需要严格控制内存使用的场景
  2. 固定大小的缓冲区实现
  3. 多线程环境下的安全数据容器
  4. 防止意外扩容导致内存溢出的场景

注意:此实现不支持动态扩容,若需可变容量应使用 ArrayList。批量操作 addAll() 具有原子性,保证操作过程中不会被其他线程修改。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐