Circular Buffer
package datastructures;
import java.util.Optional;
public class CircularBuffer {
private int start;
private int end;
private int capacity;
private final Integer[] storage;
public CircularBuffer(int maxCapacity) {
start = 0;
end = 0;
capacity = 0;
storage = new Integer[maxCapacity];
}
public void add(int number) {
if (capacity == storage.length) {
incrementStart();
}
storage[end] = number;
incrementEnd();
}
public Integer pop() {
Optional<Integer> value = Optional.ofNullable(storage[start]);
storage[start] = null;
incrementStart();
return value.orElse(null);
}
private void incrementEnd() {
end += 1;
capacity += 1;
if (end == storage.length) {
end = 0;
}
}
private void incrementStart() {
start += 1;
capacity -= 1;
if (start == storage.length) {
start = 0;
}
}
}
Test:
package unit.datastructures;
import datastructures.CircularBuffer;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
public class CircularBufferTest {
CircularBuffer circularBuffer;
@BeforeEach
public void beforeEach() {
circularBuffer = new CircularBuffer(3);
}
@Test
public void add_and_pop_givenNumber_shouldAddInCycle() {
circularBuffer.add(5);
circularBuffer.add(3);
circularBuffer.add(1);
assertEquals(5, circularBuffer.pop());
circularBuffer.add(6);
assertEquals(3, circularBuffer.pop());
assertEquals(1, circularBuffer.pop());
circularBuffer.add(4);
assertEquals(6, circularBuffer.pop());
assertEquals(4, circularBuffer.pop());
assertNull(circularBuffer.pop());
}
}