本文是 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 |
|