Java/Collections Data Structure/Queue

Материал из Java эксперт
Перейти к: навигация, поиск

Blocking Queue

  
/**
 * The utillib library.
 * More information is available at http://www.jinchess.ru/.
 * Copyright (C) 2002 Alexander Maryanovsky.
 * All rights reserved.
 *
 * The utillib library is free software; you can redistribute
 * it and/or modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * The utillib library is distributed in the hope that it will
 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with utillib library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

import java.util.Enumeration;
import java.util.Vector;
/**
 * <P>A blocking queue, one that always "contains" elements.
 * If it is in fact empty, the pop() and peek() method will block until an
 * item is pushed.
 * <P><B>NOTE:</B> This class is thread safe.
 *
 * @author Alexander Maryanovsky.
 */
public class BlockingQueue implements Cloneable{

  /**
   * The underlying Vector this BlockingQueue is using.
   */
  private final Vector queue;

  /**
   * The lock we use to synchronize pushing.
   */
  private final Object pushLock = new String("BlockingQueue pushLock");

  /**
   * The lock we use to synchronize popping.
   */
  private final Object popLock = new String("BlockingQueue popLock");


  /**
   * Creates a new, empty BlockingQueue.
   */
  public BlockingQueue(){
    queue = new Vector();
  }


  /**
   * Pushes an element into the queue.
   */
  public void push(Object object){
    synchronized(pushLock){
      queue.addElement(object);
      synchronized(this){
        notify();
      }
    }
  }

  /**
   * Pops an element from the queue. If the queue is empty, this method blocks
   * until another thread pushes an element into the queue.
   *
   * @throws InterruptedException if the invoking thread was interrupted
   * while waiting for an element to be pushed into the queue.
   */
  public Object pop() throws InterruptedException{
    return pop(0);
  }

  /**
   * Pops an element from the queue. Unlike the pop() method, this method does not block
   * for longer than the given amount of milliseconds. When the given amount of milliseconds
   * have passed, this method will throw an InterruptedException.
   */
  public Object pop(long timeout) throws InterruptedException{
    synchronized(popLock){
      synchronized(this){
        if (queue.isEmpty()){
          wait(timeout);
          if (queue.isEmpty())
            throw new InterruptedException("Timed out");
        }
      }
      Object val = queue.firstElement();
      queue.removeElementAt(0);
      return val;
    }
  }

  /**
   * Returns the element on top of the queue without popping it. If the queue
   * is empty, this method blocks until another thread pushes an element into
   * the queue.
   *
   * @throws InterruptedException if the invoking thread was interrupted while
   * waiting for an element to be pushed into the queue.
   */
  public Object peek() throws InterruptedException{
    return peek(0);
  }


  /**
   * Returns the element on top of the queue without popping it.
   * Unlike the peek() method, this method does not block
   * for longer than the given amount of milliseconds. When the given amount of milliseconds
   * have passed, this method will throw an InterruptedException.
   */
  public Object peek(long timeout) throws InterruptedException{
    synchronized(popLock){
      synchronized(this){
        if (queue.isEmpty()){
          wait(timeout);
          if (queue.isEmpty())
            throw new InterruptedException("Timed out");
        }
      }
      return queue.firstElement();
    }
  }



  /**
   * Returns true if the queue is empty (this returns the actual state of the
   * queue, meaning it may return true even though ideologically, a BlockingQueue
   * is never empty).
   */
  public boolean isEmpty(){
    return queue.isEmpty();
  }

  /**
   * Returns true if the given element is in the queue.
   */
  public boolean contains(Object element){
    return queue.contains(element);
  }

  /**
   * Returns the size of the queue.
   */
  public int size(){
    return queue.size();
  }

  /**
   * Returns an Enumeration of the elements in this queue. The order of the
   * elements is the same as if they were popped from the queue one by one (the
   * first element is the first element that would have been popped). <br>
   * <B>IMPORTANT:</B> Modifying the queue breaks the returned Enumeration.
   */
  public Enumeration getElements(){
    return queue.elements();
  }

  /**
   * Removes all elements from this queue.
   */
  public void removeAllElements(){
    queue.removeAllElements();
  }

  /**
   * Removes all elements from this queue.
   */
  public void clear(){
    queue.removeAllElements();
  }

  /**
   * Returns a shallow copy of this BlockingQueue.
   */
  public synchronized Object clone(){
    BlockingQueue copy = new BlockingQueue();
    Enumeration elems = getElements();
    while (elems.hasMoreElements()){
      Object item = elems.nextElement();
      copy.push(item);
    }
    return copy;
  }

}





Circular Queue

  
/*   Copyright 2004 BEA Systems, Inc.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

import java.util.AbstractCollection;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
public final class CircularQueue extends AbstractCollection {
  // This is the largest capacity allowed by this implementation
  private static final int MAX_CAPACITY = 1 << 30;
  private static final int DEFAULT_CAPACITY = 1 << 8;
  private int size          = 0;
  private int producerIndex = 0;
  private int consumerIndex = 0;
  // capacity must be a power of 2 at all times
  private int capacity;
  private int maxCapacity;
  // we mask with capacity -1.  This variable caches that values
  private int bitmask; 
  private Object[] q;
  public CircularQueue() {
    this(DEFAULT_CAPACITY);
  }
  // Construct a queue which has at least the specified capacity.  If
  // the value specified is a power of two then the queue will be
  // exactly the specified size.  Otherwise the queue will be the
  // first power of two which is greater than the specified value.
  public CircularQueue(int c) {
    this(c, MAX_CAPACITY);
  }
  public CircularQueue(int c, int mc) {
    if (c > mc) {
      throw new IllegalArgumentException("Capacity greater than maximum");
    }
    if (mc > MAX_CAPACITY) {
      throw new IllegalArgumentException("Maximum capacity greater than " +
        "allowed");
    }
    for (capacity = 1; capacity < c; capacity <<= 1) ;
    for (maxCapacity = 1; maxCapacity < mc; maxCapacity <<= 1) ;
    bitmask = capacity - 1;
    q = new Object[capacity];
  }
  // Constructor used by clone()
  private CircularQueue(CircularQueue oldQueue) {
    size = oldQueue.size;
    producerIndex = oldQueue.producerIndex;
    consumerIndex = oldQueue.consumerIndex;
    capacity = oldQueue.capacity;
    maxCapacity = oldQueue.maxCapacity;
    bitmask = oldQueue.bitmask;
    q = new Object[oldQueue.q.length];
    System.arraycopy(oldQueue.q, 0, q, 0, q.length);
  }
  private boolean expandQueue() {
    // double the size of the queue
    // This design assumes that this is a rare case
    if (capacity == maxCapacity) {
      return false;
    }
    int old_capacity = capacity;
    Object[] old_q    = q;
    capacity += capacity;
    bitmask   = capacity - 1;
    q         = new Object[capacity];
    System.arraycopy(old_q, consumerIndex, q, 0, old_capacity - consumerIndex);
    if (consumerIndex != 0) {
      System.arraycopy(old_q, 0, q, old_capacity - consumerIndex, 
        consumerIndex);
    }
    consumerIndex = 0;
    producerIndex = size;
    return true;
  }
  public boolean add(Object obj) {
    if (size == capacity) {
      // no room
      if (!expandQueue()) return false;
    }
    size++;
    q[producerIndex] = obj;
    producerIndex = (producerIndex + 1) & bitmask;
    return true;
  }
  public Object remove() {
    Object obj;
    
    if (size == 0) return null;
    
    size--;
    obj = q[consumerIndex];
    q[consumerIndex] = null; // allow gc to collect
    
    consumerIndex = (consumerIndex + 1) & bitmask;
    return obj;
  }
  public boolean isEmpty() { return size == 0; }
  public int size() { return size; }
  public int capacity() { return capacity; }
  public Object peek() {
    if (size == 0) return null;
    return q[consumerIndex];
  }
  public void clear() {
    Arrays.fill(q, null);
    size = 0;
    producerIndex = 0;
    consumerIndex = 0;
  }
  public Object clone() {
    return new CircularQueue(this);
  }
  public String toString() {
    StringBuffer s = new StringBuffer(super.toString() + " - capacity: "" +
      capacity() + "" size: "" + size() + """);
    if (size > 0) {
      s.append(" elements:");
      for (int i = 0; i < size; ++i) {
        s.append("\n");
        s.append("\t");
        s.append(q[consumerIndex + i & bitmask].toString());
      }      
    }
    return s.toString();
  }
  public Iterator iterator() {
    return new Iterator() {
      private final int ci = consumerIndex;
      private final int pi = producerIndex;
      private int s = size;
      private int i = ci;
      public boolean hasNext() {
        checkForModification();
        return s > 0;
      }
      public Object next() {
        checkForModification();
        if (s == 0) throw new NoSuchElementException();
    
        s--;
        Object r = q[i];
        i = (i + 1) & bitmask;
        return r;
      }
      public void remove() {
        throw new UnsupportedOperationException();
      }
      private void checkForModification() {
        if (ci != consumerIndex) throw new ConcurrentModificationException();
        if (pi != producerIndex) throw new ConcurrentModificationException();
      }
    };
  }
}





Circular Queue extends AbstractList

  
/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *  
 *    http://www.apache.org/licenses/LICENSE-2.0
 *  
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License. 
 *  
 */
import java.io.Serializable;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Queue;
/**
 * A unbounded circular queue based on array.
 * 
 * @author The Apache MINA Project (dev@mina.apache.org)
 * @version $Rev: 762170 $, $Date: 2009-04-06 00:01:18 +0200 (Mon, 06 Apr 2009) $
 */
public class CircularQueue<E> extends AbstractList<E> implements List<E>, Queue<E>, Serializable {
    /** The serialVersionUID : mandatory for serializable classes */
    private static final long serialVersionUID = 3993421269224511264L;
    /** Minimal size fo the underlying attay */
    private static final int DEFAULT_CAPACITY = 4;
    /** The initial capacity of the list */
    private final int initialCapacity;
    
    // XXX: This volatile keyword here is a workaround for SUN Java Compiler bug,
    //      which produces buggy byte code.  I don"t event know why adding a volatile
    //      fixes the problem.  Eclipse Java Compiler seems to produce correct byte code.
    private volatile Object[] items;
    private int mask;
    private int first = 0;
    private int last = 0;
    private boolean full;
    private int shrinkThreshold;
    /**
     * Construct a new, empty queue.
     */
    public CircularQueue() {
        this(DEFAULT_CAPACITY);
    }
    
    public CircularQueue(int initialCapacity) {
        int actualCapacity = normalizeCapacity(initialCapacity);
        items = new Object[actualCapacity];
        mask = actualCapacity - 1;
        this.initialCapacity = actualCapacity;
        this.shrinkThreshold = 0;
    }
    /**
     * The capacity must be a power of 2.
     */
    private static int normalizeCapacity(int initialCapacity) {
        int actualCapacity = 1;
        
        while (actualCapacity < initialCapacity) {
            actualCapacity <<= 1;
            if (actualCapacity < 0) {
                actualCapacity = 1 << 30;
                break;
            }
        }
        return actualCapacity;
    }
    /**
     * Returns the capacity of this queue.
     */
    public int capacity() {
        return items.length;
    }
    @Override
    public void clear() {
        if (!isEmpty()) {
            Arrays.fill(items, null);
            first = 0;
            last = 0;
            full = false;
            shrinkIfNeeded();
        }
    }
    @SuppressWarnings("unchecked")
    public E poll() {
        if (isEmpty()) {
            return null;
        }
        Object ret = items[first];
        items[first] = null;
        decreaseSize();
        
        if (first == last) {
            first = last = 0;
        }
        shrinkIfNeeded();
        return (E) ret;
    }
    public boolean offer(E item) {
        if (item == null) {
            throw new NullPointerException("item");
        }
        
        expandIfNeeded();
        items[last] = item;
        increaseSize();
        return true;
    }
    @SuppressWarnings("unchecked")
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        return (E) items[first];
    }
    @SuppressWarnings("unchecked")
    @Override
    public E get(int idx) {
        checkIndex(idx);
        return (E) items[getRealIndex(idx)];
    }
    @Override
    public boolean isEmpty() {
        return (first == last) && !full;
    }
    @Override
    public int size() {
        if (full) {
            return capacity();
        }
        
        if (last >= first) {
            return last - first;
        } else {
            return last - first + capacity();
        }
    }
    
    @Override
    public String toString() {
        return "first=" + first + ", last=" + last + ", size=" + size()
                + ", mask = " + mask;
    }
    private void checkIndex(int idx) {
        if (idx < 0 || idx >= size()) {
            throw new IndexOutOfBoundsException(String.valueOf(idx));
        }
    }
    private int getRealIndex(int idx) {
        return (first + idx) & mask;
    }
    private void increaseSize() {
        last = (last + 1) & mask;
        full = first == last;
    }
    private void decreaseSize() {
        first = (first + 1) & mask;
        full = false;
    }
    private void expandIfNeeded() {
        if (full) {
            // expand queue
            final int oldLen = items.length;
            final int newLen = oldLen << 1;
            Object[] tmp = new Object[newLen];
    
            if (first < last) {
                System.arraycopy(items, first, tmp, 0, last - first);
            } else {
                System.arraycopy(items, first, tmp, 0, oldLen - first);
                System.arraycopy(items, 0, tmp, oldLen - first, last);
            }
    
            first = 0;
            last = oldLen;
            items = tmp;
            mask = tmp.length - 1;
            if (newLen >>> 3 > initialCapacity) {
                shrinkThreshold = newLen >>> 3;
            }
        }
    }
    
    private void shrinkIfNeeded() {
        int size = size();
        if (size <= shrinkThreshold) {
            // shrink queue
            final int oldLen = items.length;
            int newLen = normalizeCapacity(size);
            if (size == newLen) {
                newLen <<= 1;
            }
            
            if (newLen >= oldLen) {
                return;
            }
            
            if (newLen < initialCapacity) {
                if (oldLen == initialCapacity) {
                    return;
                } else {
                    newLen = initialCapacity;
                }
            }
            
            Object[] tmp = new Object[newLen];
    
            // Copy only when there"s something to copy.
            if (size > 0) {
                if (first < last) {
                    System.arraycopy(items, first, tmp, 0, last - first);
                } else {
                    System.arraycopy(items, first, tmp, 0, oldLen - first);
                    System.arraycopy(items, 0, tmp, oldLen - first, last);
                }
            }
    
            first = 0;
            last = size;
            items = tmp;
            mask = tmp.length - 1;
            shrinkThreshold = 0;
        }
    }
    @Override
    public boolean add(E o) {
        return offer(o);
    }
    @SuppressWarnings("unchecked")
    @Override
    public E set(int idx, E o) {
        checkIndex(idx);
        int realIdx = getRealIndex(idx);
        Object old = items[realIdx];
        items[realIdx] = o;
        return (E) old;
    }
    @Override
    public void add(int idx, E o) {
        if (idx == size()) {
            offer(o);
            return;
        }
        checkIndex(idx);
        expandIfNeeded();
        int realIdx = getRealIndex(idx);
        // Make a room for a new element.
        if (first < last) {
            System
                    .arraycopy(items, realIdx, items, realIdx + 1, last
                            - realIdx);
        } else {
            if (realIdx >= first) {
                System.arraycopy(items, 0, items, 1, last);
                items[0] = items[items.length - 1];
                System.arraycopy(items, realIdx, items, realIdx + 1,
                        items.length - realIdx - 1);
            } else {
                System.arraycopy(items, realIdx, items, realIdx + 1, last
                        - realIdx);
            }
        }
        items[realIdx] = o;
        increaseSize();
    }
    @SuppressWarnings("unchecked")
    @Override
    public E remove(int idx) {
        if (idx == 0) {
            return poll();
        }
        checkIndex(idx);
        int realIdx = getRealIndex(idx);
        Object removed = items[realIdx];
        // Remove a room for the removed element.
        if (first < last) {
            System.arraycopy(items, first, items, first + 1, realIdx - first);
        } else {
            if (realIdx >= first) {
                System.arraycopy(items, first, items, first + 1, realIdx
                        - first);
            } else {
                System.arraycopy(items, 0, items, 1, realIdx);
                items[0] = items[items.length - 1];
                System.arraycopy(items, first, items, first + 1, items.length
                        - first - 1);
            }
        }
        items[first] = null;
        decreaseSize();
        shrinkIfNeeded();
        return (E) removed;
    }
    public E remove() {
        if (isEmpty()) {
            throw new NoSuchElementException();
        }
        return poll();
    }
    public E element() {
        if (isEmpty()) {
            throw new NoSuchElementException();
        }
        return peek();
    }
}
///////////////////////////////////////////////
/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *  
 *    http://www.apache.org/licenses/LICENSE-2.0
 *  
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License. 
 *  
 */
package org.apache.mina.util;
import junit.framework.TestCase;
import java.util.Iterator;
/**
 * Tests {@link org.apache.mina.util.CircularQueue}
 * 
 * @author The Apache MINA Project (dev@mina.apache.org)
 * @version $Rev: 755170 $, $Date: 2009-03-17 10:46:58 +0100 (Tue, 17 Mar 2009) $
 */
public class CircularQueueTest extends TestCase {
    private volatile int pushCount;
    private volatile int popCount;
    public void setUp() {
        pushCount = 0;
        popCount = 0;
    }
    public void testRotation() {
        CircularQueue<Integer> q = new CircularQueue<Integer>(); // DEFAULT_CAPACITY = 4
        testRotation0(q);
    }
    public void testExpandingRotation() {
        CircularQueue<Integer> q = new CircularQueue<Integer>(); // DEFAULT_CAPACITY = 4
        for (int i = 0; i < 10; i++) {
            testRotation0(q);
            // make expansion happen
            int oldCapacity = q.capacity();
            for (int j = q.capacity(); j >= 0; j--) {
                q.offer(new Integer(++pushCount));
            }
            assertTrue(q.capacity() > oldCapacity);
            testRotation0(q);
        }
    }
    private void testRotation0(CircularQueue<Integer> q) {
        for (int i = 0; i < q.capacity() * 7 / 4; i++) {
            q.offer(new Integer(++pushCount));
            assertEquals(++popCount, q.poll().intValue());
        }
    }
    public void testRandomAddOnQueue() {
        CircularQueue<Integer> q = new CircularQueue<Integer>();
        // Create a queue with 5 elements and capacity 8;
        for (int i = 0; i < 5; i++) {
            q.offer(new Integer(i));
        }
        q.add(0, new Integer(100));
        q.add(3, new Integer(200));
        q.add(7, new Integer(300));
        Iterator<Integer> i = q.iterator();
        assertEquals(8, q.size());
        assertEquals(new Integer(100), i.next());
        assertEquals(new Integer(0), i.next());
        assertEquals(new Integer(1), i.next());
        assertEquals(new Integer(200), i.next());
        assertEquals(new Integer(2), i.next());
        assertEquals(new Integer(3), i.next());
        assertEquals(new Integer(4), i.next());
        assertEquals(new Integer(300), i.next());
        try {
            i.next();
            fail();
        } catch (Exception e) {
            // an exception signifies a successfull test case
            assertTrue(true);            
        }
    }
    public void testRandomAddOnRotatedQueue() {
        CircularQueue<Integer> q = getRotatedQueue();
        q.add(0, new Integer(100)); // addFirst
        q.add(2, new Integer(200));
        q.add(4, new Integer(300));
        q.add(10, new Integer(400));
        q.add(12, new Integer(500)); // addLast
        Iterator<Integer> i = q.iterator();
        assertEquals(13, q.size());
        assertEquals(new Integer(100), i.next());
        assertEquals(new Integer(0), i.next());
        assertEquals(new Integer(200), i.next());
        assertEquals(new Integer(1), i.next());
        assertEquals(new Integer(300), i.next());
        assertEquals(new Integer(2), i.next());
        assertEquals(new Integer(3), i.next());
        assertEquals(new Integer(4), i.next());
        assertEquals(new Integer(5), i.next());
        assertEquals(new Integer(6), i.next());
        assertEquals(new Integer(400), i.next());
        assertEquals(new Integer(7), i.next());
        assertEquals(new Integer(500), i.next());
        try {
            i.next();
            fail();
        } catch (Exception e) {
            // an exception signifies a successfull test case
            assertTrue(true);
        }
    }
    public void testRandomRemoveOnQueue() {
        CircularQueue<Integer> q = new CircularQueue<Integer>();
        // Create a queue with 5 elements and capacity 8;
        for (int i = 0; i < 5; i++) {
            q.offer(new Integer(i));
        }
        q.remove(0);
        q.remove(2);
        q.remove(2);
        Iterator<Integer> i = q.iterator();
        assertEquals(2, q.size());
        assertEquals(new Integer(1), i.next());
        assertEquals(new Integer(2), i.next());
        try {
            i.next();
            fail();
        } catch (Exception e) {
            // an exception signifies a successfull test case
            assertTrue(true);
        }
    }
    public void testRandomRemoveOnRotatedQueue() {
        CircularQueue<Integer> q = getRotatedQueue();
        q.remove(0); // removeFirst
        q.remove(2); // removeLast in the first half
        q.remove(2); // removeFirst in the first half
        q.remove(4); // removeLast
        Iterator<Integer> i = q.iterator();
        assertEquals(4, q.size());
        assertEquals(new Integer(1), i.next());
        assertEquals(new Integer(2), i.next());
        assertEquals(new Integer(5), i.next());
        assertEquals(new Integer(6), i.next());
        try {
            i.next();
            fail();
        } catch (Exception e) {
            // an exception signifies a successfull test case
            assertTrue(true);            
        }
    }
    
    public void testExpandAndShrink() throws Exception {
        CircularQueue<Integer> q = new CircularQueue<Integer>();
        for (int i = 0; i < 1024; i ++) {
            q.offer(i);
        }
        
        assertEquals(1024, q.capacity());
        
        for (int i = 0; i < 512; i ++) {
            q.offer(i);
            q.poll();
        }
        
        assertEquals(2048, q.capacity());
        
        for (int i = 0; i < 1024; i ++) { 
            q.poll();
        }
        
        assertEquals(4, q.capacity());
    }
    private CircularQueue<Integer> getRotatedQueue() {
        CircularQueue<Integer> q = new CircularQueue<Integer>();
        // Ensure capacity: 16
        for (int i = 0; i < 16; i++) {
            q.offer(new Integer(-1));
        }
        q.clear();
        // Rotate it
        for (int i = 0; i < 12; i++) {
            q.offer(new Integer(-1));
            q.poll();
        }
        // Now push items
        for (int i = 0; i < 8; i++) {
            q.offer(new Integer(i));
        }
        return q;
    }
    public static void main(String[] args) {
        junit.textui.TestRunner.run(CircularQueueTest.class);
    }
}





Convert a Queue to a List

   
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class Main {
  public static void main(String[] args) {
    Queue<String> myQueue = new LinkedList<String>();
    myQueue.add("A");
    myQueue.add("B");
    myQueue.add("C");
    myQueue.add("D");
    List<String> myList = new ArrayList<String>(myQueue);
    for (Object theFruit : myList)
      System.out.println(theFruit);
  }
}
/*
A
B
C
D
*/





Create a queue using LinkedList class

   
 
import java.util.LinkedList;
import java.util.Queue;
public class Main {
  public static void main(String[] args) {
    Queue<String> queue = new LinkedList<String>();
    queue.offer("First");
    queue.offer("Second");
    queue.offer("Third");
    queue.offer("Fourth");
    System.out.println("Size: " + queue.size());
    System.out.println("Queue head using peek   : " + queue.peek());
    System.out.println("Queue head using element: " + queue.element());
    Object data;
    while ((data = queue.poll()) != null) {
      System.out.println(data);
    }
  }
}





Priority queue

public class PriorityQ {
  // array in sorted order, from max at 0 to min at size-1
  private int maxSize;
  private long[] queArray;
  private int nItems;
  public PriorityQ(int s) {
    maxSize = s;
    queArray = new long[maxSize];
    nItems = 0;
  }
  public void insert(long item) {
    int i;
    if (nItems == 0)
      queArray[nItems++] = item; // insert at 0
    else 
    {
      for (i = nItems - 1; i >= 0; i--) // start at end,
      {
        if (item > queArray[i]) // if new item larger,
          queArray[i + 1] = queArray[i]; // shift upward
        else
          // if smaller,
          break; // done shifting
      }
      queArray[i + 1] = item; // insert it
      nItems++;
    } // end else (nItems > 0)
  }
  public long remove(){
    return queArray[--nItems];
  }
  public long peekMin(){
    return queArray[nItems - 1];
  }
  public boolean isEmpty(){
    return (nItems == 0);
  }
  public boolean isFull(){
    return (nItems == maxSize);
  }
  public static void main(String[] args) {
    PriorityQ thePQ = new PriorityQ(5);
    thePQ.insert(30);
    thePQ.insert(50);
    thePQ.insert(10);
    thePQ.insert(40);
    thePQ.insert(20);
    while (!thePQ.isEmpty()) {
      long item = thePQ.remove();
      System.out.print(item + " "); // 10, 20, 30, 40, 50
    }
    System.out.println("");
  }
}





Queue data structure

   
public class Queue {
  private int maxSize;
  private long[] queArray;
  private int front;
  private int rear;
  private int nItems;
  public Queue(int s) {
    maxSize = s;
    queArray = new long[maxSize];
    front = 0;
    rear = -1;
    nItems = 0;
  }
  //   put item at end of a queue
  public void insert(long j) {
    if (rear == maxSize - 1) // deal with wraparound
      rear = -1;
    queArray[++rear] = j; // increment rear and insert
    nItems++; 
  }
  //   take item from front of queue
  public long remove() {
    long temp = queArray[front++]; // get value and incr front
    if (front == maxSize) // deal with wraparound
      front = 0;
    nItems--; // one less item
    return temp;
  }
  public long peekFront() {
    return queArray[front];
  }
  public boolean isEmpty() {
    return (nItems == 0);
  }
  public boolean isFull() {
    return (nItems == maxSize);
  }
  public int size() {
    return nItems;
  }
  public static void main(String[] args) {
    Queue theQueue = new Queue(5); // queue holds 5 items
    theQueue.insert(10);
    theQueue.insert(20);
    theQueue.insert(30);
    theQueue.insert(40);
    theQueue.remove(); 
    theQueue.remove(); 
    theQueue.remove();
    theQueue.insert(50); 
    theQueue.insert(60); //    (wraps around)
    theQueue.insert(70);
    theQueue.insert(80);
    while (!theQueue.isEmpty()) {
      long n = theQueue.remove(); // (40, 50, 60, 70, 80)
      System.out.print(n);
      System.out.print(" ");
    }
    System.out.println("");
  }
}





Simple Queue (FIFO) based on LinkedList

  
// Copyright (c) 2003-2009, Jodd Team (jodd.org). All Rights Reserved.

import java.util.LinkedList;
/**
 * Simple Queue (FIFO) based on LinkedList.
 */
public class SimpleQueue<E> {
  private LinkedList<E> list = new LinkedList<E>();
  /**
   * Puts object in queue.
   */
  public void put(E o) {
    list.addLast(o);
  }
  /**
   * Returns an element (object) from queue.
   *
   * @return element from queue or <code>null</code> if queue is empty
   */
  public E get() {
    if (list.isEmpty()) {
      return null;
    }
    return list.removeFirst();
  }
  /**
   * Returns all elements from the queue and clears it.
   */
  public Object[] getAll() {
    Object[] res = new Object[list.size()];
    for (int i = 0; i < res.length; i++) {
      res[i] = list.get(i);
    }
    list.clear();
    return res;
  }

  /**
   * Peeks an element in the queue. Returned elements is not removed from the queue.
   */
  public E peek() {
    return list.getFirst();
  }
  /**
   * Returns <code>true</code> if queue is empty, otherwise <code>false</code>
   */
  public boolean isEmpty() {
    return list.isEmpty();
  }
  /**
   * Returns queue size.
   */
  public int size() {
    return list.size();
  }
}





The Generic Queue Class

    

import java.util.LinkedList;
class GenQueue<E> {
  private LinkedList<E> list = new LinkedList<E>();
  public void enqueue(E item) {
    list.addLast(item);
  }
  public E dequeue() {
    return list.poll();
  }
  public boolean hasItems() {
    return !list.isEmpty();
  }
  public int size() {
    return list.size();
  }
  public void addItems(GenQueue<? extends E> q) {
    while (q.hasItems())
      list.addLast(q.dequeue());
  }
}
public class GenQueueTest {
  public static void main(String[] args) {
    GenQueue<Employee> empList;
    empList = new GenQueue<Employee>();
    GenQueue<HourlyEmployee> hList;
    hList = new GenQueue<HourlyEmployee>();
    hList.enqueue(new HourlyEmployee("T", "D"));
    hList.enqueue(new HourlyEmployee("G", "B"));
    hList.enqueue(new HourlyEmployee("F", "S"));
    empList.addItems(hList);
    while (empList.hasItems()) {
      Employee emp = empList.dequeue();
      System.out.println(emp.firstName + " " + emp.lastName);
    }
  }
}
class Employee {
  public String lastName;
  public String firstName;
  public Employee() {
  }
  public Employee(String last, String first) {
    this.lastName = last;
    this.firstName = first;
  }
  public String toString() {
    return firstName + " " + lastName;
  }
}
class HourlyEmployee extends Employee {
  public double hourlyRate;
  public HourlyEmployee(String last, String first) {
    super(last, first);
  }
}