自定义 Java 集合:如何基于 AbstractList 实现一个支持固定容量的安全列表
·
基于 AbstractList 实现固定容量安全列表
核心设计思路
- 容量固定:初始化时指定容量,不可动态扩容
- 线程安全:所有修改操作使用
synchronized同步 - 边界校验:所有操作进行索引边界检查
- 元素访问:支持安全的读写操作
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;
}
}
关键特性说明
-
容量限制:
- 初始化后容量固定,
add()操作在满容时抛出IllegalStateException - 示例:
new FixedCapacityList<String>(5)创建最大容量为 5 的列表
- 初始化后容量固定,
-
线程安全机制:
public synchronized boolean add(E element) { ... }所有修改方法使用同步锁,确保多线程环境下的数据一致性
-
边界保护:
checkIndex()方法验证所有访问操作的合法性- 非法访问抛出
IndexOutOfBoundsException
-
内存管理:
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"); // 成功(现在有空位)
适用场景
- 需要严格控制内存使用的场景
- 固定大小的缓冲区实现
- 多线程环境下的安全数据容器
- 防止意外扩容导致内存溢出的场景
注意:此实现不支持动态扩容,若需可变容量应使用
ArrayList。批量操作addAll()具有原子性,保证操作过程中不会被其他线程修改。
更多推荐
所有评论(0)