import java.util.Scanner;
/**
* Implementation of homework 7.
*
* @author Cheng Yu
* @assignment ICS211 Homework TA7
* @date Oct 24, 2008
* @bugs None
*/
public class ChengJade07 {
/**
* The main entry point of the program.
*
* @param args The command line arguments (not used).
*/
public static void main(final String[] args) {
// Create a scanner to read from standard input.
final Scanner scanner = new Scanner(System.in);
// Create an array queue used to hold the data.
// final Queue<String> queue = new ArrayQueue<String>();
final Queue<String> queue = new LinkedListQueue<String>();
// Loop until the user quits.
while (true) {
// Display a menu of options.
System.out.println("You may choose one of the following options:\n");
System.out.println(" 1) 'quit' - quits the program.");
System.out.println(" 2) 'null' - adds a null String to the queue.");
System.out.println(" 3) 'poll' - polls the next String from the queue.");
System.out.println(" 4) Anything else is inserted into the queue.");
System.out.print("\nYour option: ");
System.out.flush();
// Get the command from the user.
if (!scanner.hasNextLine())
break;
final String input = scanner.nextLine();
// Check for quit command.
if (input.equals("quit"))
break;
// Check for the poll command. Poll the next String and display it in
// this case.
if (input.equals("poll")) {
System.out.println("Poll returned '" + queue.poll() + "'.");
continue;
}
// Check for the null command. Add a null String in this case.
if (input.equals("null")) {
System.out.println("Offer returned '" + queue.offer(null) + "'.");
continue;
}
// Anything else is offered to the queue.
System.out.println("Offer returned '" + queue.offer(input) + "'.");
}
// Allow the Eclipse debugger to exit happily.
System.exit(0);
}
}
/**
* An array queue, implemented with a circular buffer.
*/
class ArrayQueue<T> implements Queue<T> {
/** The maximum size of the queue. */
public static final int MAX_SIZE = 10;
/** The circular buffer. */
private final T[] myQueue = newArray(MAX_SIZE);
/** The number of items in the queue. */
private int mySize = 0;
/** A pointer to the next available element in the array for adding. */
private int myTail = 0;
/**
* Returns an array of the generic type. It is unclear if this is safe, but
* the general feeling at sun.com is that it is.
*
* @see http://forums.sun.com/thread.jspa?threadID=530823
* @return An array for the generic type.
*/
@SuppressWarnings("unchecked")
public T[] newArray(final int size) {
return (T[])(new Object[size]);
}
/**
* Returns the absolute index based on a virtual index. This simplifies the
* amount of code required to compute the index values in the circular buffer.
*
* @param virtualIndex The virtual index.
* @return The absolute index.
*/
private int at(final int virtualIndex) {
assert virtualIndex >= 0 && virtualIndex <= MAX_SIZE;
return (MAX_SIZE + myTail + virtualIndex - mySize) % MAX_SIZE;
}
/**
* Offers an item to the queue.
*
* @param value The item to add to the queue.
* @return True if the item is added and false otherwise.
*/
public boolean offer(final T value) {
// Return false if the queue is full.
if (mySize == MAX_SIZE)
return false;
// Return false if the value is null.
if (value == null)
return false;
// Loop over each item and return false if the new item already exists.
for (int i = 0; i < mySize; i++)
if (myQueue[at(i)].equals(value))
return false;
// Add the item, and update the pointer and size.
myQueue[at(mySize)] = value;
myTail = at(mySize + 1);
mySize++;
// Return true to indicate the item was added successfully.
return true;
}
/**
* Polls the queue. The first added item is removed if it exists.
*
* @return The first added item if it exists or null otherwise.
*/
public T poll() {
// Return false if there are no items in the queue.
if (mySize == 0)
return null;
// Return the item at the head of the queue, and adjust the size.
final T result = myQueue[at(0)];
mySize--;
// Return the item removed successfully.
return result;
}
}
/**
* The interface to a generic queue.
*/
interface Queue<T> {
/**
* Offers an item to the queue.
*
* @param value The item to add to the queue.
* @return True if the item is added and false otherwise.
*/
boolean offer(T value);
/**
* Polls the queue. The first added item is removed if it exists.
*
* @return The first added item if it exists or null otherwise.
*/
T poll();
}
/**
* A generic linked list class
*/
class LinkedListQueue<T> implements Queue<T> {
/** The head of the linked list. */
private Node<T> myHead;
/**
* Offers an item to the queue.
*
* @param value The item to add to the queue.
* @return True if the item is added and false otherwise.
*/
public boolean offer(final T value) {
// Do not allow null values to be added.
if (value == null)
return false;
// Add the item to the head of the list if it is the first item.
if (myHead == null) {
myHead = new Node<T>(value, myHead);
return true;
}
// Do not add if the item equals the value in the head of the linked list.
if(myHead.value().equals(value))
return false;
// Loop over each item in the linked list to see if the item already exists
// in the collection. If the item exists, return false.
Node<T> node;
for (node = myHead; node.next() != null; node = node.next())
if (node.next().value().equals(value))
return false;
// Add the item to the end of the linked list and return true.
node.setNext(new Node<T>(value, null));
return true;
}
/**
* Polls the queue. The first added item is removed if it exists.
*
* @return The first added item if it exists or null otherwise.
*/
public T poll() {
// Return null if there are no items in the linked list.
if (myHead == null)
return null;
// Return the item at the head, and remove the head.
final T result = myHead.value();
myHead = myHead.next();
return result;
}
}
/**
* A generic node class.
*/
class Node<T> {
/** A pointer to the next node */
private Node<T> myNext;
/** The value in the node. */
private final T myValue;
/**
* Initializes a new instance of the class.
*
* @param value The value stored in this node.
* @param next A pointer to the next node.
*/
public Node(final T value, final Node<T> next) {
assert null != value;
myValue = value;
myNext = next;
}
/**
* Returns the pointer to the next node.
*
* @return The pointer to the next node.
*/
public Node<T> next() {
return myNext;
}
/**
* Returns the value stored in this node.
*
* @return The value stored in this node.
*/
public T value() {
return myValue;
}
/**
* Sets the pointer to the next node.
*
* @param next The pointer to the next node.
*/
public void setNext(final Node<T> next) {
myNext = next;
}
}