Queue<String> queue = new LinkedList<>();  // Queue interface uses LL implementation
queue.add("John");
queue.add("Jane");
queue.add("Bob");
// Collections has a toArray conversion
Object[] arr = queue.toArray();
// Iterate of array
System.out.println("Iterate over Array");
for (Object a : arr){
    // Type is Object from conversion
    System.out.println(a);
    // remove() method is called to remove and print the next element in the queue
}
Iterate over Array
John
Jane
Bob
// Empty queue
System.out.println("Empty Queue");
while (queue.size() > 0) // Interate while size
    System.out.println(queue.remove());
    // remove() method is called to remove and print the next element in the queue

System.out.println(queue);
Empty Queue
John
Jane
Bob
[]
/* 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 smallSize to establish key order
	public abstract String toString();

	// static print method smallSize by extended classes
	public static void print(Generics[] objs) {
		// print 'Object' properties
		// System.out.println(objs.getClass() + " " + objs.length);
		System.out.println(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 Turtle extends Generics {

    public static KeyTypes key = KeyType.title;
	public static void setOrder(KeyTypes key) { Turtle.key = key; }
	public enum KeyType implements KeyTypes {title, name, age, weight, smallSize}

	private final String name;
	private final int age;
	private final double weight;
    private final boolean smallSize;

	public Turtle(String name, int age, double weight, boolean smallSize)
	{
		super.setType("Turtle");
		this.name = name;
		this.age = age;
		this.weight = weight;
        this.smallSize = smallSize; 
	}

	@Override
	protected KeyTypes getKey() { return Turtle.key; }
	

	@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.weight.equals(this.getKey())) {
			output += this.weight; 
		} else if (KeyType.smallSize.equals(this.getKey())) {
			output += this.smallSize;
		} else {
			output += super.getType() + ": " + this.name + ", " + this.smallSize + ", " + this.age + ", " + this.weight;
		}
		return output;
		
	}

	// Test data initializer
	public static Turtle[] Turtles() {
		return new Turtle[]{
			new Turtle("Shellbert", 5, 2.22, false),
			new Turtle("Eggbert", 4, 3.34, true),
			new Turtle("Seabert", 3, 6.54, true)		
		};
	}
	

	public static void main(String[] args)
	{
		// Inheritance Hierarchy
		Turtle[] objs = Turtles();

		// print with title
		Turtle.setOrder(KeyType.title);
		Turtle.print(objs);

		// print name only
		Turtle.setOrder(KeyType.name);
		Turtle.print(objs);

		// print by weight only
		Turtle.setOrder(KeyType.weight);
		Turtle.print(objs);
	}

}
Turtle.main(null);
3
Generic: Turtle listed by title
Turtle: Shellbert, false, 5, 2.22
Turtle: Eggbert, true, 4, 3.34
Turtle: Seabert, true, 3, 6.54

3
Generic: Turtle listed by name
Shellbert
Eggbert
Seabert

3
Generic: Turtle listed by weight
2.22
3.34
6.54

/**
 *  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);
    }
}
/**
 * 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);
    }

    /**
     * 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.queue.add(data);
                this.count++;
            }
    }

    /**
     * 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();
    }
}
/**
 * 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 NCS Generics
        Turtle.setOrder(Turtle.KeyType.name);
        
        // Illustrates use of a series of repeating arguments
        QueueManager qGenerics = new QueueManager("My Generics", Turtle.Turtles());
        qGenerics.printQueue();
        
        qGenerics.queue.add(new Turtle("Beachbert", 5, 5.22, false));
        
        qGenerics.printQueue();
        
        qGenerics.queue.add(new Turtle("Sheldon", 7, 4.42, false));

        qGenerics.queue.delete();
        
        qGenerics.printQueue();

        qGenerics.queue.delete();
        
        qGenerics.printQueue();

    }
}
QueueTester.main(null);
My Generics count: 3
My Generics data: Shellbert Eggbert Seabert 
My Generics count: 3
My Generics data: Shellbert Eggbert Seabert Beachbert 
My Generics count: 3
My Generics data: Eggbert Seabert Beachbert Sheldon 
My Generics count: 3
My Generics data: Seabert Beachbert Sheldon 

FRQ 2018 Q4

class Main {
    public static void main(String[] args) {
        int[][] arr1 = {{0,1,2}, {1, 2, 0}, {2, 0, 1}};
        int[][] arr2 = {{0,1,2}, {1, 2, 0}, {2, 1, 0}};
        
        printArray(arr1);
        System.out.println(ArrayTester.isLatin(arr1)); 

        printArray(arr2);
        System.out.println(ArrayTester.isLatin(arr2));
    }
    
    public static void printArray(int[][] arr) {
        for(int[] i: arr) {
            for(int j: i) {
                System.out.print(j + "\t");
            }
            System.out.println();
        }
    }
}

class ArrayTester {
    public static int[] getColumn(int[][] arr, int col) {
        int[] column = new int[arr.length];
        for(int i = 0; i < arr.length; i++) {
            column[i] = arr[i][col];
        }
        return column;
    }
    
    public static boolean hasAllValues(int[] arr1, int[] arr2) {
        for(int i = 0; i < arr1.length; i++) {
            boolean found = false;
            for(int j = 0; j < arr2.length; j++) {
                if(arr1[i] == arr2[j]) {
                    found = true;
                    break;
                }
            }
            if(!found) {
                return false;
            }
        }
        return true;
    }
    
    public static boolean containsDuplicates(int[] arr) {  
        for(int i = 0; i < arr.length - 1; i++) {
            if(arr[i] == arr[i+1]) {
                return true;
            }
        }
        System.out.print("Result: ");
        return false;
    }
    
    public static boolean isLatin(int[][] square) { 
        if(containsDuplicates(square[0])) {
            return false;
        }
        
        for(int i = 1; i < square.length; i++) {
            if(!hasAllValues(square[0], square[i]) || !hasAllValues(square[0], getColumn(square, i))) {
                return false;
            }
        }
        return true;
    }
}

Main.main(null);
0	1	2	
1	2	0	
2	0	1	
Result: true
0	1	2	
1	2	0	
2	1	0	
Result: false

Checkpoint #2

Challenge 1

/**
 * 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[] { "Serendipity", "Quixotic", "Melancholy", "Perfidious", "Ephemeral"};
        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();

    }
}
QueueTester.main(null);
Words count: 5
Words data: Serendipity Quixotic Melancholy Perfidious Ephemeral 
Integers count: 10
Integers data: 0 1 2 3 4 5 6 7 8 9 
import java.util.Iterator;

public class LinkedList<T> {
    private T data;
    private LinkedList<T> prevNode, nextNode;

    // Create new node with T data and reference to previous LinkedList<T> node
    public LinkedList(T data, LinkedList<T> node) {
        setData(data);
        setPrevNode(node);
        setNextNode(null);
    }

    // Create new node using copy
    public LinkedList(LinkedList<T> node) {
        setData(node.data);
        setPrevNode(node.prevNode);
        setNextNode(node.nextNode);
    }

    // Getters
    public T getData() {
        return this.data;
    }

    public LinkedList<T> getPrev() {
        return this.prevNode;
    }

    public LinkedList<T> getNext() {
        return this.nextNode;
    }

    // Setters
    public void setData(T data) {
        this.data = data;
    }

    public void setPrevNode(LinkedList<T> node) {
        this.prevNode = node;
    }

    public void setNextNode(LinkedList<T> node) {
        this.nextNode = node;
    }
}

/**
 * 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() {
        try {
            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;
        } catch (Exception E) {
            return null;
        }
        
    }

    /**
     *  Returns the data of head.
     *
     * @return  this.head.getData(), the head data in Queue.
     */
    public T peek() {
        try {
            return this.head.getData();
        } catch (Exception E) {
            return null;
        }
    }

    /**
     *  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);
    }
}
/**
 * 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);
    }

    /**
     * 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.queue.add(data);
                this.count++;
            }
    }

    // Challenge 1 
    public T delete() {
        count--;
        return this.queue.delete();
    }

    /**
     * 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();
    }
}

/**
 * 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[] { "Serendipity", "Quixotic", "Melancholy", "Perfidious", "Ephemeral"};
        QueueManager qWords = new QueueManager("Words", words );
        qWords.printQueue();

        while (qWords.delete() != null) {
            qWords.printQueue();
        }
    }
}
QueueTester.main(null);
Words count: 5
Words data: Serendipity Quixotic Melancholy Perfidious Ephemeral 
Words count: 4
Words data: Quixotic Melancholy Perfidious Ephemeral 
Words count: 3
Words data: Melancholy Perfidious Ephemeral 
Words count: 2
Words data: Perfidious Ephemeral 
Words count: 1
Words data: Ephemeral 
Words count: 0
Words data: