packagecom.madooei.cb.circulards;importcom.madooei.cb.exception.EmptyException;publicclassCircularBuffer<T>{privateT[] data;privateint numElements;privateint writePos;// 写指针(可认为是队尾)privateint readPos;// 读指针(可认为是队首)// Constructor: create buffer with given capacitypublicCircularBuffer(int capacity){this.data =(T[])newObject[capacity];this.numElements =0;this.writePos =0;this.readPos =0;}// Add element to buffer (overwrites oldest if full)publicvoidwrite(T element){writePos =(readPos + numElements)% data.length;data[writePos]= element;if(isFull()){// 当缓冲区已满时,写入新元素不仅要前移写指针,还需要**同步前移读指针**,以确保新的写入位置始终有效,// 并维持先进先出的顺序。readPos =(readPos +1)% data.length;}else{numElements++;}}// Remove and return oldest elementpublicTread(){if(isEmpty()){thrownewEmptyException("You can not read from empty circular buffer");}T elemnt = data[readPos];readPos =(readPos +1)% data.length;numElements--;return elemnt;}// Check if buffer is emptypublicbooleanisEmpty(){return numElements ==0;}// Check if buffer is fullpublicbooleanisFull(){return numElements >= data.length;}// Get current number of elementspublicintsize(){return numElements;}// 查看当前队首的元素,不删除publicTpeek(){if(isEmpty()){thrownewEmptyException("You can not peek from empty circular buffer");}return data[readPos];}}
测试用例
packagecom.madooei.cb.circulards;importorg.junit.jupiter.api.Assertions;importorg.junit.jupiter.api.Test;publicclassCircularBufferTest{@Testpublicvoidtest(){CircularBuffer<String> buffer =newCircularBuffer<>(3);buffer.write("A");buffer.write("B");buffer.write("C");// Buffer: [A, B, C] (full)Assertions.assertEquals("A", buffer.peek());buffer.write("D");// Overwrites "A"// Buffer: [D, B, C] conceptually, but A is overwrittenAssertions.assertEquals("B", buffer.peek());String first = buffer.read();// Returns "B"Assertions.assertEquals("B", first);Assertions.assertEquals("C", buffer.peek());String second = buffer.read();// Returns "C"Assertions.assertEquals("C", second);// Buffer now contains just "D"buffer.write("E");buffer.write("F");Assertions.assertEquals("D", buffer.peek());buffer.write("G");Assertions.assertEquals("E", buffer.peek());}}
环形缓冲区示例用法
CircularBuffer<String> buffer =newCircularBuffer<>(3);buffer.write("A");
buffer.write("B");
buffer.write("C");// Buffer: [A, B, C] (full)buffer.write("D");// Overwrites "A"// Buffer: [D, B, C] conceptually, but A is overwrittenString first = buffer.read();// Returns "B"String second = buffer.read();// Returns "C"// Buffer now contains just "D"buffer.write("E");
buffer.write("F");// Buffer: [D, E, F]
示例追踪
CircularBuffer<String> buffer = new CircularBuffer<>(3);数组:[][][]
写指针`back`:0
读指针`front`:0
numElements:0buffer.write("A");
数组:[A][][]
写指针`back`:1
读指针`front`:0
numElements:1buffer.write("B");
数组:[A][B][]
写指针`back`:2
读指针`front`:0
numElements:2buffer.write("C");
// Buffer: [A, B, C] (full)
数组:[A][B][C]
写指针`back`:0
读指针`front`:0
numElements:3buffer.write("D"); // Overwrites "A"
数组:[D][B][C]
写指针`back`:1 // 前移写指针
读指针`front`:1 // 前移读指针
numElements:3// Buffer: [D, B, C] conceptually, but A is overwrittenString first = buffer.read(); // Returns "B"
数组:[D][null][C]
写指针`back`:1
读指针`front`:2 // 前移读指针
numElements:2String second = buffer.read(); // Returns "C"
数组:[D][null][null]
写指针`back`:1
读指针`front`:0 // 前移读指针
numElements:1
// Buffer now contains just "D"buffer.write("E");
数组:[D][E][null]
写指针`back`:2
读指针`front`:0
numElements:2buffer.write("F");
数组:[D][E][F]
写指针`back`:0
读指针`front`:0
numElements:3
// Buffer: [D, E, F]buffer.write("G");
数组:[G][E][F]
写指针`back`:1
读指针`front`:1 // 前移读指针
numElements:3
// Buffer: [G, E, F]