Table of Contents
In my spare time lately I’ve been writing this Android football game, and for the game I needed a simple FIFO queue. I haven’t used Java much lately, and after a quick Google search showed things that were more complicated than what I had in mind, I wrote my own FIFO queue.
FIFO queue with a size limit
This isn’t a pure FIFO queue in that I wanted to limit the number of elements that could be kept in the queue. The way it should work is that if I add more elements than the queue can contain, the queue should silently drop the oldest (first-in) element.
That being said, the source code shown below is very easily made into a more simple FIFO queue, as shown at the end of this article.
I named my new class FifoQueueWithLimitedSize
, and I create an instance of it like this:
private final FifoQueueWithLimitedSize<String> previousOffensivePlays = new FifoQueueWithLimitedSize<>(3);
Here I create previousOffensivePlays
to keep track of the last three plays called by the computer when it’s running the offense. Later on I add elements to the queue like this:
previousOffensivePlays.put(currentOffensivePlay);
Given that introduction of how to use this FIFO queue, here’s the Java source code for it:
import java.util.LinkedList; import java.util.List; /** * A FIFO queue, written by Alvin Alexander (http://alvinalexander.com). * * As its name implies, this is a first-in, first-out queue. * * I developed this class for a football game I'm writing, where I want to remember * a limited number of plays that the "Computer Offensive Coordinator" has * previously called. The current need is that I don't want the computer calling * the same play three times in a row. * * I was going to add a `reverse` method here, but you can do that in Java with * `Collections.reverse(list)`, so I didn't think there was a need for it. * */ public class FifoQueueWithLimitedSize<E> { private List<E> list = new LinkedList<>(); private int maxSize = 3; public FifoQueueWithLimitedSize(int maxSize) { this.maxSize = maxSize; } public void put(E e) { list.add(e); if (list.size() > maxSize) list.remove(0); } /** * can return `null` */ public E pop() { if (list.size() > 0) { E e = list.get(0); list.remove(0); return e; } else { return null; //but have a nice day } } /** * @throws IndexOutOfBoundsException */ public E peek() { return list.get(0); } public boolean contains(E e) { return list.contains(e); } /** * @throws IndexOutOfBoundsException */ public E get(int i) { return list.get(i); } public List<E> getBackingList() { // return a copy of the list return new LinkedList<>(list); } public void clear() { list.clear(); } public boolean isEmpty() { return list.isEmpty(); } // mostly needed for testing atm public int size() { return list.size(); } }
Some of those methods might not be used by a traditional queue, but they helped make my life a little easier, so I added them.
FIFO queue tests
I didn’t test the queue code too hard, but FWIW, here is one series of unit tests that I wrote for it:
public void testMaxQueueSizeWorks() throws Exception { FifoQueueWithLimitedSize<String> q = new FifoQueueWithLimitedSize<>(3); assertEquals("initial queue size is 0", 0, q.size()); q.put("a"); assertEquals("size after adding 'a' element is 1", 1, q.size()); q.put("b"); assertEquals("size after adding 'b' element is 2", 2, q.size()); q.put("c"); assertEquals("size after adding 'c' element is 3", 3, q.size()); q.put("d"); assertEquals("size after adding 'd' element is still 3", 3, q.size()); q.put("e"); assertEquals("size after adding 'e' element is still 3", 3, q.size()); assertEquals("element 0 should be 'c'", "c", q.get(0)); assertEquals("element 1 should be 'd'", "d", q.get(1)); assertEquals("element 2 should be 'e'", "e", q.get(2)); }
I like test code because it helps to serve as documentation for the source code that’s being tested, and in this case it helps to show how I expect this queue to work.
A “regular” FIFO queue
Note that this class is easily modified to be a FIFO queue without a size limit. You only need to change a few lines of code to make that happen. In fact, what the heck, here are those changes that give you a “regular” Java FIFO queue:
public class FifoQueue<E> { private List<E> list = new LinkedList<>(); public void put(E e) { list.add(e); } /** * can return `null` */ public E pop() { if (list.size() > 0) { E e = list.get(0); list.remove(0); return e; } else { return null; //but have a nice day } } /** * @throws IndexOutOfBoundsException */ public E peek() { return list.get(0); } public boolean contains(E e) { return list.contains(e); } /** * @throws IndexOutOfBoundsException */ public E get(int i) { return list.get(i); } public List<E> getBackingList() { // return a copy of the list return new LinkedList<>(list); } public void clear() { list.clear(); } public boolean isEmpty() { return list.isEmpty(); } // mostly needed for testing atm public int size() { return list.size(); } }
Note that the pop
behavior in this class is different than a Java LinkedList, which works like a stack. This code pops the first (0th) element off of the queue.
Summary
In summary, if you were looking for some Java source code for a FIFO queue, I hope this code is helpful.