本文是 RingList 源代码。
这种数据结构,类似于环形缓冲(Ring Buffer),但是仅保留最后的 N 项数据,为解决类似于 “获取当前网站最新 50 个事件”这样的问题而设计的。
内部使用了一个固定大小的数组来存储,由一个指针指向下一个存储位置,存满后指向第一个位置,覆盖存储,所以只能存储最近的 N 项数据,实际上就是一个环形结构。
取值方法默认倒序。考虑到这种数据结构常常在多线程环境下使用(如 web),所以存储、读取使用了锁,应该是线程安全的。
import java.lang.reflect.Array;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class RingList<T> {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private transient Object[] elementData;
private final int capacity;
private int index = 0;
private int size = 0;
public RingList(int capacity) {
if (capacity <= 0) {
throw new IllegalArgumentException("Invalid capacity: " + capacity);
}
this.capacity = capacity;
this.elementData = new Object[capacity];
}
public int size() {
return size;
}
public void add(T e) {
Lock writeLock = lock.writeLock();
writeLock.lock();
try {
if (index >= capacity) {
index = 0;
}
elementData[index] = e;
index++;
if (size < capacity) {
size++;
}
} finally {
writeLock.unlock();
}
}
public Object[] toArray(){
return fillResultArray(new Object[size]);
}
public T[] toArray(Class<T> clazz){
T[] result = (T[]) Array.newInstance(clazz, size);
return (T[]) fillResultArray(result);
}
private Object[] fillResultArray(Object[] result){
Lock readLock = lock.readLock();
readLock.lock();
try{
for(int x = 0 , i = index ; x < size ; x++){
i--;
if(i < 0){
i = capacity - 1;
}
result[x] = (T) elementData[i];
}
return result;
}finally {
readLock.unlock();
}
}
public void clear(){
Lock writeLock = lock.writeLock();
writeLock.lock();
try {
index = 0;
size = 0;
elementData = new Object[capacity];
} finally {
writeLock.unlock();
}
}
}
| Source |
|