Circular Buffer
From:http://bradforj287.blogspot.com/2010/11/efficient-circular-buffer-in-java.html
1 import java.util.NoSuchElementException; 2 /** 3 * Thread safe fixed size circular buffer implementation. Backed by an array. 4 * 5 * @author brad 6 */ 7 public class ArrayCircularBuffer<T> { 8 // internal data storage 9 private T[] data; 10 // indices for inserting and removing from queue 11 private int front = 0; 12 private int insertLocation = 0; 13 // number of elements in queue 14 private int size = 0; 15 /** 16 * Creates a circular buffer with the specified size. 17 * 18 * @param bufferSize 19 * - the maximum size of the buffer 20 */ 21 public ArrayCircularBuffer(int bufferSize) { 22 data = (T[]) new Object[bufferSize]; 23 } 24 /** 25 * Inserts an item at the end of the queue. If the queue is full, the oldest 26 * value will be removed and head of the queue will become the second oldest 27 * value. 28 * 29 * @param item 30 * - the item to be inserted 31 */ 32 public synchronized void insert(T item) { 33 data[insertLocation] = item; 34 insertLocation = (insertLocation + 1) % data.length; 35 /** 36 * If the queue is full, this means we just overwrote the front of the 37 * queue. So increment the front location. 38 */ 39 if (size == data.length) { 40 front = (front + 1) % data.length; 41 } else { 42 size++; 43 } 44 } 45 /** 46 * Returns the number of elements in the buffer 47 * 48 * @return int - the number of elements inside this buffer 49 */ 50 public synchronized int size() { 51 return size; 52 } 53 /** 54 * Returns the head element of the queue. 55 * 56 * @return T 57 */ 58 public synchronized T removeFront() { 59 if (size == 0) { 60 throw new NoSuchElementException(); 61 } 62 T retValue = data[front]; 63 front = (front + 1) % data.length; 64 size--; 65 return retValue; 66 } 67 /** 68 * Returns the head of the queue but does not remove it. 69 * 70 * @return 71 */ 72 public synchronized T peekFront() { 73 if (size == 0) { 74 return null; 75 } else { 76 return data[front]; 77 } 78 } 79 /** 80 * Returns the last element of the queue but does not remove it. 81 * 82 * @return T - the most recently added value 83 */ 84 public synchronized T peekLast() { 85 if (size == 0) { 86 return null; 87 } else { 88 int lastElement = insertLocation - 1; 89 if (lastElement < 0) { 90 lastElement = data.length - 1; 91 } 92 return data[lastElement]; 93 } 94 } 95 }