diff --git a/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/fixedsizequeues/FifoFixedSizeQueue.java b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/fixedsizequeues/FifoFixedSizeQueue.java new file mode 100644 index 0000000000..2937b4f55c --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/fixedsizequeues/FifoFixedSizeQueue.java @@ -0,0 +1,79 @@ +package com.baeldung.collections.fixedsizequeues; + +import java.util.AbstractQueue; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class FifoFixedSizeQueue extends AbstractQueue { + + /** The queued items */ + final Object[] items; + + /** Number of elements in the queue */ + int count; + + public FifoFixedSizeQueue(int capacity) { + super(); + + items = new Object[capacity]; + count = 0; + } + + @Override + public boolean offer(E e) { + if (e == null) { + throw new NullPointerException("Queue doesn't allow nulls"); + } + if (count == items.length) { + this.poll(); + } + this.items[count] = e; + count++; + return true; + } + + @Override + public E poll() { + if (count <= 0) { + return null; + } + E item = (E) items[0]; + shiftLeft(); + count--; + return item; + } + + private void shiftLeft() { + int i = 1; + while (i < items.length) { + if (items[i] == null) { + break; + } + items[i - 1] = items[i]; + i++; + } + } + + @Override + public E peek() { + if (count <= 0) { + return null; + } + return (E) items[0]; + } + + @Override + public int size() { + return count; + } + + @Override + public Iterator iterator() { + List list = new ArrayList<>(count); + for (int i = 0; i < count; i++) { + list.add((E) items[i]); + } + return list.iterator(); + } +} diff --git a/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/collections/fixedsizequeues/FifoFixedSizeQueueUnitTest.java b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/collections/fixedsizequeues/FifoFixedSizeQueueUnitTest.java new file mode 100644 index 0000000000..6ffd289ce9 --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/collections/fixedsizequeues/FifoFixedSizeQueueUnitTest.java @@ -0,0 +1,133 @@ +package com.baeldung.collections.fixedsizequeues; + +import java.util.Iterator; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; + +public class FifoFixedSizeQueueUnitTest { + + @Test + void givenEmptyQueue_whenIterating_thenHasNextIsFalse() { + FifoFixedSizeQueue toTest = new FifoFixedSizeQueue<>(10); + Iterator i = toTest.iterator(); + assertFalse(i.hasNext()); + } + + @Test + void givenEmptyQueue_whenOffer_thenCountIsOne() { + FifoFixedSizeQueue toTest = new FifoFixedSizeQueue<>(10); + toTest.offer("1"); + assertEquals(1, toTest.size()); + } + + @Test + void givenEmptyQueue_whenPeek_thenNull() { + FifoFixedSizeQueue toTest = new FifoFixedSizeQueue<>(10); + String tail = toTest.peek(); + assertNull(tail); + } + + @Test + void givenEmptyQueue_whenPoll_thenNull() { + FifoFixedSizeQueue toTest = new FifoFixedSizeQueue<>(10); + String dequeued = toTest.poll(); + assertNull(dequeued); + } + + @Test + void givenNonEmptyQueue_whenIterating_thenHasNextIsTrue() { + FifoFixedSizeQueue toTest = new FifoFixedSizeQueue<>(10); + Iterator i = toTest.iterator(); + assertFalse(i.hasNext()); + } + + @Test + void givenNonEmptyQueue_whenOffer_thenCountMatchesQueueElements() { + FifoFixedSizeQueue toTest = new FifoFixedSizeQueue<>(10); + toTest.offer("1"); + toTest.offer("2"); + assertEquals(2, toTest.size()); + } + + @Test + void givenNonEmptyQueue_whenPeek_thenFirstElementMustBeReturned() { + String expectedElement = "1"; + + FifoFixedSizeQueue toTest = new FifoFixedSizeQueue<>(10); + toTest.offer(expectedElement); + toTest.offer("2"); + + assertEquals(expectedElement, toTest.peek()); + assertEquals(expectedElement, toTest.peek()); + } + + @Test + void givenNonEmptyQueue_whenPoll_thenFirstElementMustBeReturnedAndRemoved() { + String expectedPoll = "1"; + String expectedTailAfterPoll = "2"; + + FifoFixedSizeQueue toTest = new FifoFixedSizeQueue<>(10); + toTest.offer(expectedPoll); + toTest.offer(expectedTailAfterPoll); + + assertEquals(expectedPoll, toTest.poll()); + assertEquals(expectedTailAfterPoll, toTest.peek()); + } + + @Test + void givenFullQueue_whenOffer_thenRemovedOldestFromTailAndOffer() { + FifoFixedSizeQueue toTest = new FifoFixedSizeQueue<>(2); + toTest.offer("1"); + toTest.offer("2"); + toTest.offer("3"); + + Iterator i = toTest.iterator(); + assertEquals("2", i.next()); + assertEquals("3", i.next()); + assertFalse(i.hasNext()); + } + + @Test + void whenPoll_thenSizeDecreases() { + FifoFixedSizeQueue toTest = new FifoFixedSizeQueue<>(2); + toTest.offer("1"); + + toTest.poll(); + assertEquals(0, toTest.size()); + } + + @Test + void whenOffer_thenSizeIncreases() { + FifoFixedSizeQueue toTest = new FifoFixedSizeQueue<>(2); + toTest.offer("1"); + assertEquals(1, toTest.size()); + } + + @Test + void givenFullQueue_whenOffer_thenElementIsInsertedAndSizeEqualsCapacity() { + FifoFixedSizeQueue toTest = new FifoFixedSizeQueue<>(2); + toTest.offer("1"); + toTest.offer("2"); + toTest.offer("3"); + assertEquals(2, toTest.size()); + assertEquals("2", toTest.peek()); + } + + @Test + void givenEmptyQueue_whenSizeRequest_thenZero() { + FifoFixedSizeQueue toTest = new FifoFixedSizeQueue<>(2); + assertEquals(0, toTest.size()); + } + + @Test + void givenEmptyQueue_whenPoll_thenReturnNullAndSizeIsZero() { + FifoFixedSizeQueue toTest = new FifoFixedSizeQueue<>(2); + assertNull(toTest.poll()); + assertEquals(0, toTest.size()); + } + +}