Notes

  • class can make an object
  • an interface allows you to define the methods that you want in the class, you cannot instantiate them
  • each class is automatically an object
  • making a copy of an array adds to the space complexity
    • 2 nested loops , complexity of the algorithmn is double because it requires you to loop twice
  • you can convert from an object reference type to an array reference type to change the behavior of the code
  • java has built in toString() on basically everything
  • Abstract class: is a restricted class that cannot be used to create objects, it can have abstract and nonabstract methods, it can have constructors and static methods, it can have final methods
  • Abstract method: can only be used in an abstract class, and it does not have a body.
  • making one thing that works for all the instantiated object is what static does
  • link list allows you to add and remove the objects?
  • linked list has data and collections
  • each node has a data that must be connected to other nodes
  • they each have data and they need to point to each other
  • ex: each individual cupcakes would be the nodes
  • nodes would be added and removed. you would have to manage all the references to the cupcake to make it work
  • the data strcture must be trained to iterate
  • group of individual objects represented by a single unit is called a collection
  • There is a collection framework and map
    • framework - a set olf classes and interfaces that are ready made
  • interfaces are made up of methods that do not have a body
  • classes implement those methods and build the bodies within the class interfaces cannnot be used to create objects
  • in implementing an interface, you have to override all of its methods
  • interface methods are by default abstract and public
  • interface attributes are by default public, static, and final
Queue<String> queue = new LinkedList<>();  // Queue interface uses LL implementation
queue.add("John");
queue.add("Jane");
queue.add("Bob");
// Collections has a toArray convertion
Object[] arr = queue.toArray();

// Empty queue
System.out.println("Empty Queue");
while (queue.size() > 0) // Interate while size
    System.out.println(queue.remove());

// Iterate of array
System.out.println("Iterate over Array");
for (Object a : arr) // Type is Object from convertion
    System.out.println(a);
Empty Queue
John
Jane
Bob
Iterate over Array
John
Jane
Bob

Notes from CollegeBoard

  • constructing objects using classes
  • not having a void requires you to specific the return type from the function
  • accessor methods get(); they return a value
  • mutator/modifier methods; they change the state of the object
  • calling methods on objects
  • declare the name of the class, then the name of the object, then the equals, then new "class"
  • object.method() is the format
  • calling static methods in classes
  • static methodsdo not use object.method() convention it uses class.method()
  • you dont have to cresate these methods
  • ex: Math class, Math.abs(-45);
  • these are static methods
  • using the string class
  • String is a class to create objects with
  • object.method() format since these are not static metods

LinkedList

  • similar to an arraylist
  • you can add, change, remove items, and clear the list
  • they differ because arraylist stores elements in the array and once the array is not big enough, it creates a new array to replace the old one
  • LinkedList store items in containers
    • the list has a link to each container and each container has a link to the next item in the lsit
    • to add an elementto the list, a new container is created and that container is linked to the other containers
  • LinkedList is better for manipulating data
  • elements are lined using pointers and adresses
  • each element is known as a node and a separate object
  • ListedList is a dynamic array that does not need to specific the size while creating it
  • LinkList a = new ListedList() -- empty LinkedList
  • LinkedList a = new LinkedList(Collection C) -- creates an ordered list that contains elements from a specific collection

Queue

  • linear ordered data structure
  • element inserted first in the queue will be te first element to be removed
  • queue is an interface tat inherits the collection interface
  • queue has two ends, the front and rear
  • elements are added at the rear and removed from the front
  • bottom to top kinda like throwing up
  • queue is an interface so it cannot be instanitated
  • classes need to implement the functionality of the queue
  • linkedlist implements the queue interface
  • the queuve provides methods like insertion and deletion
  • Queue a = new LinkedList<> ();</li> </ul>

    Stack

    • stack is faster than queue
    • stack data structure
    • last in first out
    • push and pop operations
    • empty, search, peek operations
    • Stack stack = new Stack();</li>
    • </ul> </div> </div> </div>

      Generic T and Iterable Interface

      • Iterators are used to retrieve elements one by one
      • Iterator interface is used when designing custom data structures
      • need to implement iterable interface and its methods
      • cursor or pointer keeps track of what element that we are currently on
      • to progress from one element to another the next() method is used which returns the current element and advances the cursor to the next
      • hasNext() check if there is another element for the pointer to advance to, false if the end of the collection is reached
      • remove() removes the last element retgutrned by the iterator from the collection
      • forEachRemaining() performs given action for each remaining element in a collection, in sequential order
      • in a linkedlist the cursor is initialized to the head elemet or the entry point into the list or the first node
      • iterable interface allows an object to be the target of enhaved for loop
      • T is the type of element returned by the Iterator
      • universla iterator can be applied to any collection object
      • generics allow for reusable components of code rather than creating a variety of the same thing, parameterize a class, method, or interface
      • T stands for Type, unspecifed Type of data or parameter
      • T can only be used for objects and wrappers not primitives
      • When using Generics the T goes away in place of anything that can extend the object class
        • which primitives cannot do
      • Generics are beneficial because they have better compile- time checking, reusability, and great for data structures and algorithmns
      /* This is wrapper class...
       Objective would be to push more functionality into this Class to enforce consistent definition
       */
      public abstract class Generics {
      	public final String masterType = "Generic";
      	private String type;	// extender should define their data type
      
      	// generic enumerated interface
      	public interface KeyTypes {
      		String name();
      	}
      	protected abstract KeyTypes getKey();  	// this method helps force usage of KeyTypes
      
      	// getter
      	public String getMasterType() {
      		return masterType;
      	}
      
      	// getter
      	public String getType() {
      		return type;
      	}
      
      	// setter
      	public void setType(String type) {
      		this.type = type;
      	}
      	
      	// this method is used to establish key order
      	public abstract String toString();
      
      	// static print method used by extended classes
      	public static void print(Generics[] objs) {
      		// print 'Object' properties
      		System.out.println(objs.getClass() + " " + objs.length);
      
      		// print 'Generics' properties
      		if (objs.length > 0) {
      			Generics obj = objs[0];	// Look at properties of 1st element
      			System.out.println(
      					obj.getMasterType() + ": " + 
      					obj.getType() +
      					" listed by " +
      					obj.getKey());
      		}
      
      		// print "Generics: Objects'
      		for(Object o : objs)	// observe that type is Opaque
      			System.out.println(o);
      
      		System.out.println();
      	}
      }
      
      public class Level extends Generics {
          public static KeyTypes key = KeyType.title;
          public static void setOrder(KeyTypes key) { Level.key = key; }
          public enum KeyType implements KeyTypes {title, number, name, topic, difficulty, time, hint, hintContent}
      
          private final int number;
          private final String name;
          private final String topic;
          private final String difficulty;
          private final int time;
          private final boolean hint;
          private final String hintContent;
      
          public Level(int number, String name, String topic, String difficulty, int time, boolean hint, String hintContent) {
              super.setType("Level");
              this.number = number;
              this.name = name;
              this.topic = topic;
              this.difficulty = difficulty;
              this.time = time;
              this.hint = hint;
              this.hintContent = hintContent;
          }
      
          @Override
          protected KeyTypes getKey() { return Level.key; }
      
          @Override
          public String toString() {
              String output="";
              if (KeyType.number.equals(this.getKey())) {
                  output += "00" + this.number;
                  output = output.substring(output.length() - 2);
              }
              else if (KeyType.name.equals(this.getKey())) {
      			output += this.name;
              }
              else if (KeyType.topic.equals(this.getKey())) {
      			output += this.topic;
              }
              else if (KeyType.difficulty.equals(this.getKey())) {
      			output += this.difficulty;
              }
              else if (KeyType.time.equals(this.getKey())) {
                  output += "00" + this.time;
                  output = output.substring(output.length() - 2);
              }
              else if (KeyType.hint.equals(this.getKey())) {
      			output += this.hint;
              }
              else if (KeyType.hintContent.equals(this.getKey())) {
      			output += this.hintContent;
              }
              else {
      			output += super.getType() + ": " + this.number + ", " + this.topic + ", " + this.difficulty  + ", " + this.time  + ", " + this.hint  + ", " + this.hintContent;
      		}
              return output;
              
          }
      
          public static Level[] levels() {
              return new Level[]{
                              new Level(1, "The Village","If Statements", "Easy", 30, true, "Try debugging"),
                              new Level(2,"The Jungle", "For Loops", "Medium", 60, false, "Take your time"),
                              new Level(3, "The Forest","De Morgan's Law", "Hard", 90, true, "Make a table for true and false"),
              };
          }
      
          public static void main(String[] args){
              Level[] objs = levels();
      
              Level.setOrder(KeyType.title);
              Level.print(objs);
      
              Level.setOrder(KeyType.name);
              Level.print(objs);
      
              Level.setOrder(KeyType.difficulty);
              Level.print(objs);
          }
      
      }
      Level.main(null);
      
      class [LREPL.$JShell$22G$Level; 3
      Generic: Level listed by title
      Level: 1, If Statements, Easy, 30, true, Try debugging
      Level: 2, For Loops, Medium, 60, false, Take your time
      Level: 3, De Morgan's Law, Hard, 90, true, Make a table for true and false
      
      class [LREPL.$JShell$22G$Level; 3
      Generic: Level listed by name
      The Village
      The Jungle
      The Forest
      
      class [LREPL.$JShell$22G$Level; 3
      Generic: Level listed by difficulty
      Easy
      Medium
      Hard
      
      
      public class Cupcake extends Generics {
      	// Class data
      	public static KeyTypes key = KeyType.title;  // static initializer
      	public static void setOrder(KeyTypes key) {Cupcake.key = key;}
      	public enum KeyType implements KeyTypes {title, flavor, frosting, sprinkles}
      
      	// Instance data
      	private final String frosting;
      	private final int sprinkles;
      	private final String flavor;
      
      	// Constructor
      	Cupcake(String frosting, int sprinkles, String flavor)
      	{
      		this.setType("Cupcake");
      		this.frosting = frosting;
      		this.sprinkles = sprinkles;
      		this.flavor = flavor;
      	}
      
      	/* 'Generics' requires getKey to help enforce KeyTypes usage */
      	@Override
      	protected KeyTypes getKey() { return Cupcake.key; }
      
      	/* 'Generics' requires toString override
      	 * toString provides data based off of Static Key setting
      	 */
      	@Override
      	public String toString() {		
      		String output="";
      		if (KeyType.flavor.equals(this.getKey())) {
      			output += this.flavor;
      		} else if (KeyType.frosting.equals(this.getKey())) {
      			output += this.frosting;
      		} else if (KeyType.sprinkles.equals(this.getKey())) {
      			output += "00" + this.sprinkles;
      			output = output.substring(output.length() - 2);
      		} else {
      			output = super.getType() + ": " + this.flavor + ", " + this.frosting + ", " + this.sprinkles;
      		}
      		return output;
      	}
      
      	// Test data initializer
      	public static Cupcake[] cupcakes() {
      		return new Cupcake[]{
      				new Cupcake("Red", 4, "Red Velvet"),
      			    new Cupcake("Orange", 5, "Orange"),
      			    new Cupcake("Yellow", 6, "Lemon"),
      			    new Cupcake("Green", 7, "Apple"),
      			    new Cupcake("Blue", 8, "Blueberry"),
      			    new Cupcake("Purple", 9, "Blackberry"),
      			    new Cupcake("Pink", 10, "Strawberry"),
      			    new Cupcake("Tan", 11, "Vanilla"),
      			    new Cupcake("Brown", 12, "Chocolate"),
      		};
      	}
      	
      	public static void main(String[] args)
      	{
      		// Inheritance Hierarchy
      		Cupcake[] objs = cupcakes();
      
      		// print with title
      		Cupcake.setOrder(KeyType.title);
      		Cupcake.print(objs);
      
      		// print flavor only
      		Cupcake.setOrder(KeyType.flavor);
      		Cupcake.print(objs);
      	}
      	
      }
      Cupcake.main(null);
      
      class [LREPL.$JShell$25$Cupcake; 9
      Generic: Cupcake listed by title
      Cupcake: Red Velvet, Red, 4
      Cupcake: Orange, Orange, 5
      Cupcake: Lemon, Yellow, 6
      Cupcake: Apple, Green, 7
      Cupcake: Blueberry, Blue, 8
      Cupcake: Blackberry, Purple, 9
      Cupcake: Strawberry, Pink, 10
      Cupcake: Vanilla, Tan, 11
      Cupcake: Chocolate, Brown, 12
      
      class [LREPL.$JShell$25$Cupcake; 9
      Generic: Cupcake listed by flavor
      Red Velvet
      Orange
      Lemon
      Apple
      Blueberry
      Blackberry
      Strawberry
      Vanilla
      Chocolate
      
      
      /*
       * Animal class extends Generics and defines abstract methods
       */
      public class Animal extends Generics {
      	// Class data
      	public static KeyTypes key = KeyType.title;  // static initializer
      	public static void setOrder(KeyTypes key) { Animal.key = key; }
      	public enum KeyType implements KeyTypes {title, name, age, color}
      
      	// Instance data
      	private final String name;
      	private final int age;
      	private final String color;
      
      	/* constructor
      	 *
      	 */
      	public Animal(String name, int age, String color)
      	{
      		super.setType("Animal");
      		this.name = name;
      		this.age = age;
      		this.color = color;
      	}
      
      	/* 'Generics' requires getKey to help enforce KeyTypes usage */
      	@Override
      	protected KeyTypes getKey() { return Animal.key; }
      	
      	/* 'Generics' requires toString override
      	 * toString provides data based off of Static Key setting
      	 */
      	@Override
      	public String toString()
      	{
      		String output="";
      		if (KeyType.name.equals(this.getKey())) {
      			output += this.name;
      		} else if (KeyType.age.equals(this.getKey())) {
      			output += "00" + this.age;
      			output = output.substring(output.length() - 2);
      		} else if (KeyType.color.equals(this.getKey())) {
      			output += this.color;
      		} else {
      			output += super.getType() + ": " + this.name + ", " + this.color + ", " + this.age;
      		}
      		return output;
      		
      	}
      
      	// Test data initializer
      	public static Animal[] animals() {
      		return new Animal[]{
      				new Animal("Lion", 8, "Gold"),
      				new Animal("Pig", 3, "Pink"),
      				new Animal("Robin", 7, "Red"),
      				new Animal("Cat", 10, "Black"),
      				new Animal("Kitty", 1, "Calico"),
      				new Animal("Dog", 14, "Brown")
      		};
      	}
      	
      	/* main to test Animal class
      	 * 
      	 */
      	public static void main(String[] args)
      	{
      		// Inheritance Hierarchy
      		Animal[] objs = animals();
      
      		// print with title
      		Animal.setOrder(KeyType.title);
      		Animal.print(objs);
      
      		// print name only
      		Animal.setOrder(KeyType.name);
      		Animal.print(objs);
      	}
      
      }
      Animal.main(null);
      
      class [LREPL.$JShell$27$Animal; 6
      Generic: Animal listed by title
      Animal: Lion, Gold, 8
      Animal: Pig, Pink, 3
      Animal: Robin, Red, 7
      Animal: Cat, Black, 10
      Animal: Kitty, Calico, 1
      Animal: Dog, Brown, 14
      
      class [LREPL.$JShell$27$Animal; 6
      Generic: Animal listed by name
      Lion
      Pig
      Robin
      Cat
      Kitty
      Dog
      
      
      public class Alphabet extends Generics {
      	// Class data
      	public static KeyTypes key = KeyType.title;  // static initializer
      	public static void setOrder(KeyTypes key) {Alphabet.key = key;}
      	public enum KeyType implements KeyTypes {title, letter}
      	private static final int size = 26;  // constant used in data initialization
      
      	// Instance data
      	private final char letter;
      	
      	/*
      	 * single letter object
      	 */
      	public Alphabet(char letter)
      	{
      		this.setType("Alphabet");
      		this.letter = letter;
      	}
      
      	/* 'Generics' requires getKey to help enforce KeyTypes usage */
      	@Override
      	protected KeyTypes getKey() { return Alphabet.key; }
      
      	/* 'Generics' requires toString override
      	 * toString provides data based off of Static Key setting
      	 */
      	@Override
      	public String toString()
      	{
      		String output="";
      		if (KeyType.letter.equals(this.getKey())) {
      			output += this.letter;
      		} else {
      			output += super.getType() + ": " + this.letter;
      		}
      		return output;
      	}
      
      	// Test data initializer for upper case Alphabet
      	public static Alphabet[] alphabetData()
      	{
      		Alphabet[] alphabet = new Alphabet[Alphabet.size];
      		for (int i = 0; i < Alphabet.size; i++)
      		{
      			alphabet[i] = new Alphabet( (char)('A' + i) );
      		} 	
      		return alphabet;
      	}
      	
      	/* 
      	 * main to test Animal class
      	 */
      	public static void main(String[] args)
      	{
      		// Inheritance Hierarchy
      		Alphabet[] objs = alphabetData();
      
      		// print with title
      		Alphabet.setOrder(KeyType.title);
      		Alphabet.print(objs);
      
      		// print letter only
      		Alphabet.setOrder(KeyType.letter);
      		Alphabet.print(objs);
      	}
      	
      }
      Alphabet.main(null);
      
      class [LREPL.$JShell$29$Alphabet; 26
      Generic: Alphabet listed by title
      Alphabet: A
      Alphabet: B
      Alphabet: C
      Alphabet: D
      Alphabet: E
      Alphabet: F
      Alphabet: G
      Alphabet: H
      Alphabet: I
      Alphabet: J
      Alphabet: K
      Alphabet: L
      Alphabet: M
      Alphabet: N
      Alphabet: O
      Alphabet: P
      Alphabet: Q
      Alphabet: R
      Alphabet: S
      Alphabet: T
      Alphabet: U
      Alphabet: V
      Alphabet: W
      Alphabet: X
      Alphabet: Y
      Alphabet: Z
      
      class [LREPL.$JShell$29$Alphabet; 26
      Generic: Alphabet listed by letter
      A
      B
      C
      D
      E
      F
      G
      H
      I
      J
      K
      L
      M
      N
      O
      P
      Q
      R
      S
      T
      U
      V
      W
      X
      Y
      Z
      
      
      /**
       *  Implementation of a Double Linked List;  forward and backward links point to adjacent Nodes.
       *
       */
      
       public class LinkedList<T>
       {
           private T data;
           private LinkedList<T> prevNode, nextNode;
       
           /**
            *  Constructs a new element
            *
            * @param  data, data of object
            * @param  node, previous node
            */
           public LinkedList(T data, LinkedList<T> node)
           {
               this.setData(data);
               this.setPrevNode(node);
               this.setNextNode(null);
           }
       
           /**
            *  Clone an object,
            *
            * @param  node  object to clone
            */
           public LinkedList(LinkedList<T> node)
           {
               this.setData(node.data);
               this.setPrevNode(node.prevNode);
               this.setNextNode(node.nextNode);
           }
       
           /**
            *  Setter for T data in DoubleLinkedNode object
            *
            * @param  data, update data of object
            */
           public void setData(T data)
           {
               this.data = data;
           }
       
           /**
            *  Returns T data for this element
            *
            * @return  data associated with object
            */
           public T getData()
           {
               return this.data;
           }
       
           /**
            *  Setter for prevNode in DoubleLinkedNode object
            *
            * @param node, prevNode to current Object
            */
           public void setPrevNode(LinkedList<T> node)
           {
               this.prevNode = node;
           }
       
           /**
            *  Setter for nextNode in DoubleLinkedNode object
            *
            * @param node, nextNode to current Object
            */
           public void setNextNode(LinkedList<T> node)
           {
               this.nextNode = node;
           }
       
       
           /**
            *  Returns reference to previous object in list
            *
            * @return  the previous object in the list
            */
           public LinkedList<T> getPrevious()
           {
               return this.prevNode;
           }
       
           /**
            *  Returns reference to next object in list
            *
            * @return  the next object in the list
            */
           public LinkedList<T> getNext()
           {
               return this.nextNode;
           }
       
       }
      
      import java.util.Iterator;
      
      /**
       * Queue Iterator
       *
       * 1. "has a" current reference in Queue
       * 2. supports iterable required methods for next that returns a generic T Object
       */
      class QueueIterator<T> implements Iterator<T> {
          LinkedList<T> current;  // current element in iteration
      
          // QueueIterator is pointed to the head of the list for iteration
          public QueueIterator(LinkedList<T> head) {
              current = head;
          }
      
          // hasNext informs if next element exists
          public boolean hasNext() {
              return current != null;
          }
      
          // next returns data object and advances to next position in queue
          public T next() {
              T data = current.getData();
              current = current.getNext();
              return data;
          }
      }
      
      /**
       * Queue: custom implementation
       * @author     John Mortensen
       *
       * 1. Uses custom LinkedList of Generic type T
       * 2. Implements Iterable
       * 3. "has a" LinkedList for head and tail
       */
      public class Queue<T> implements Iterable<T> {
          LinkedList<T> head = null, tail = null;
      
          /**
           *  Add a new object at the end of the Queue,
           *
           * @param  data,  is the data to be inserted in the Queue.
           */
          public void add(T data) {
              // add new object to end of Queue
              LinkedList<T> tail = new LinkedList<>(data, null);
      
              if (this.head == null)  // initial condition
                  this.head = this.tail = tail;
              else {  // nodes in queue
                  this.tail.setNextNode(tail); // current tail points to new tail
                  this.tail = tail;  // update tail
              }
          }
      
          /**
           *  Returns the data of head.
           *
           * @return  data, the dequeued data
           */
          public T delete() {
              T data = this.peek();
              if (this.tail != null) { // initial condition
                  this.head = this.head.getNext(); // current tail points to new tail
                  if (this.head != null) {
                      this.head.setPrevNode(tail);
                  }
              }
              return data;
          }
      
          /**
           *  Returns the data of head.
           *
           * @return  this.head.getData(), the head data in Queue.
           */
          public T peek() {
              return this.head.getData();
          }
      
          /**
           *  Returns the head object.
           *
           * @return  this.head, the head object in Queue.
           */
          public LinkedList<T> getHead() {
              return this.head;
          }
      
          /**
           *  Returns the tail object.
           *
           * @return  this.tail, the last object in Queue
           */
          public LinkedList<T> getTail() {
              return this.tail;
          }
      
          /**
           *  Returns the iterator object.
           *
           * @return  this, instance of object
           */
          public Iterator<T> iterator() {
              return new QueueIterator<>(this.head);
          }
          
          
      }
      
      import java.util.*;
      /**
       * Queue Manager
       * 1. "has a" Queue
       * 2. support management of Queue tasks (aka: titling, adding a list, printing)
       */
      class QueueManager<T> {
          // queue data
          private final String name; // name of queue
          private int count = 0; // number of objects in queue
          public final Queue<T> queue = new Queue<>(); // queue object
      
          /**
           *  Queue constructor
           *  Title with empty queue
           */
          public QueueManager(String name) {
              this.name = name;
          }
      
          /**
           *  Queue constructor
           *  Title with series of Arrays of Objects
           */
          public QueueManager(String name, T[]... seriesOfObjects) {
              this.name = name;
              this.addList(seriesOfObjects);
              this.deleteList(seriesOfObjects);
          }
      
          /**
           * Add a list of objects to queue
           */
          public void addList(T[]... seriesOfObjects) {  //accepts multiple generic T lists
              for (T[] objects: seriesOfObjects)
                  for (T data : objects) {
                      this.count++;
                      System.out.println("Enquenced data: " + data);
                      this.queue.add(data);
                      System.out.print(this.name + " count: " + count + ", data: ");
                      for (T x:queue)
                          System.out.print(x + " ");
                      System.out.println();
                      System.out.println();
                  }
          }
      
          public void deleteList(T[]... seriesOfObjects) {
              for (T[] objects: seriesOfObjects)
                  for (T data : objects) {
                      this.count--;
                      System.out.println("Dequeued data: " + data);
                      this.queue.delete();
                      System.out.print(this.name + " count: " + count + ", data: ");
                      for (T x:queue)
                          System.out.print(x + " ");
                      System.out.println();
                      System.out.println();
                  }
          }
          
      
          /**
           * Print any array objects from queue
           */
          public void printQueue() {
              System.out.println(this.name + " count: " + count);
              System.out.print(this.name + " data: ");
              for (T data : queue)
                  System.out.print(data + " ");
              System.out.println();
          }
      }
      
      import java.util.*;
      /**
       * Driver Class
       * Tests queue with string, integers, and mixes of Classes and types
       */
      class QueueTester {
          public static void main(String[] args)
          {
              // Create iterable Queue of Words
              Object[] words = new String[] { "seven", "slimy", "snakes", "sallying", "slowly", "slithered", "southward"};
              QueueManager qWords = new QueueManager("Words", words );
              qWords.printQueue();
          }
      }
      QueueTester.main(null);
      
      Enquenced data: seven
      Words count: 1, data: seven 
      
      Enquenced data: slimy
      Words count: 2, data: seven slimy 
      
      Enquenced data: snakes
      Words count: 3, data: seven slimy snakes 
      
      Enquenced data: sallying
      Words count: 4, data: seven slimy snakes sallying 
      
      Enquenced data: slowly
      Words count: 5, data: seven slimy snakes sallying slowly 
      
      Enquenced data: slithered
      Words count: 6, data: seven slimy snakes sallying slowly slithered 
      
      Enquenced data: southward
      Words count: 7, data: seven slimy snakes sallying slowly slithered southward 
      
      Dequeued data: seven
      Words count: 6, data: slimy snakes sallying slowly slithered southward 
      
      Dequeued data: slimy
      Words count: 5, data: snakes sallying slowly slithered southward 
      
      Dequeued data: snakes
      Words count: 4, data: sallying slowly slithered southward 
      
      Dequeued data: sallying
      Words count: 3, data: slowly slithered southward 
      
      Dequeued data: slowly
      Words count: 2, data: slithered southward 
      
      Dequeued data: slithered
      Words count: 1, data: southward 
      
      Dequeued data: southward
      Words count: 0, data: 
      
      Words count: 0
      Words data: 
      
      /**
       * Driver Class
       * Tests queue with string, integers, and mixes of Classes and types
       */
      class QueueTester {
          public static void main(String[] args)
          {
              // Create iterable Queue of Words
              Object[] words = new String[] { "seven", "slimy", "snakes", "sallying", "slowly", "slithered", "southward"};
              QueueManager qWords = new QueueManager("Words", words );
              qWords.printQueue();
      
              // Create iterable Queue of Integers
              Object[] numbers = new Integer[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
              QueueManager qNums = new QueueManager("Integers", numbers );
              qNums.printQueue();
      
              // Create iterable Queue of NCS Generics
              Animal.setOrder(Animal.KeyType.name);
              Alphabet.setOrder(Alphabet.KeyType.letter);
              Cupcake.setOrder(Cupcake.KeyType.flavor);
              Level.setOrder(Level.KeyType.name);
              // Illustrates use of a series of repeating arguments
              QueueManager qGenerics = new QueueManager("My Generics",
                      Alphabet.alphabetData(),
                      Animal.animals(),
                      Cupcake.cupcakes(),
                      Level.levels()
              );
              qGenerics.printQueue();
      
              // Create iterable Queue of Mixed types of data
              QueueManager qMix = new QueueManager("Mixed");
              qMix.queue.add("Start");
              qMix.addList(
                      words,
                      numbers,
                      Alphabet.alphabetData(),
                      Animal.animals(),
                      Cupcake.cupcakes(),
                      Level.levels()
              );
              qMix.queue.add("End");
              qMix.printQueue();
          }
      }
      QueueTester.main(null);
      
      Words count: 7
      Words data: seven slimy snakes sallying slowly slithered southward 
      Integers count: 10
      Integers data: 0 1 2 3 4 5 6 7 8 9 
      My Generics count: 44
      My Generics data: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Lion Pig Robin Cat Kitty Dog Red Velvet Orange Lemon Apple Blueberry Blackberry Strawberry Vanilla Chocolate The Village The Jungle The Forest 
      Mixed count: 61
      Mixed data: Start seven slimy snakes sallying slowly slithered southward 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Lion Pig Robin Cat Kitty Dog Red Velvet Orange Lemon Apple Blueberry Blackberry Strawberry Vanilla Chocolate The Village The Jungle The Forest End 
      
      </div>