Blog and Define the details of a Class

Access Modifiers

Access modifiers determine the level of access or visibility of a class, method, or variable from other parts of the program. There are four access modifiers: public, private, protected, and default (also known as package-private).

Public access modifier: The class, method, or variable can be accessed from anywhere in the program, even from outside the package.

Private access modifier: The class, method, or variable can only be accessed within the same class.

Protected access modifier: Allows access within the same class and any subclasses, as well as classes in the same package.

Default access modifier: (no keyword is used) restricts access to within the same package.

public String a = "Public";
private String b = "Private";
protected String c = "Protected";
String d = "Default";

public class Public {
}

private class Private {
}

protected class Protected {
}

class Default {
}

Constructors

A constructor is a type of method that is used to initialize objects of a class. It has the same name as the class and does not have a return type (not even void). A constructor is called when an object of a class is created using the "new" keyword. It initializes the instance variables of the object and sets it up for use. Constructors can be parameterized, meaning they can accept parameters, or they can be default constructors with no parameters.

public class Car {
    private String make;
    private String model;
 
    // Constructor
    public Car(String make, String model) {
       this.make = make;
       this.model = model;
    }
}

Getters

Getters are methods that provide access to the private fields of a class. They are used to retrieve the value of a private field from an instance of a class. By using getters, we can keep the data encapsulated within the class, while still providing access to it from outside the class.

public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }
    //Getter Method
    public String getName() { 
        return this.name; //accesses the private String name
    }
}

Setters

Setters are methods that provide a way to update the value of a private field in a class.They are used to modify the value of a private field from outside the class. By using setters, we can keep the data encapsulated within the class and provide a controlled way to update it.

public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
    //Setter Method
    public void setName(String name) {
        this.name = name; //Updates the value of private String name
    }
}
/* 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();
	}
}
/**
 *  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; 
    LinkedList<T> node = 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> extends Queue<T>{
    // queue data
    private final String name; // name of queue
    protected 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 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);
        // // Illustrates use of a series of repeating arguments
        // QueueManager qGenerics = new QueueManager("My Generics",
        //         Alphabet.alphabetData(),
        //         Animal.animals(),
        //         Cupcake.cupcakes()
        // );
        // 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() 
        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 
Mixed count: 17
Mixed data: Start seven slimy snakes sallying slowly slithered southward 0 1 2 3 4 5 6 7 8 9 End 

Start of My Code

import java.util.Random; 
/**
 * Queue Manager
 * 1. "has a" Queue
 * 2. support management of Queue tasks (aka: titling, adding a list, printing)
 */
class QueueChange<T> {
    // queue data
    private final String name; // name of queue
    protected int count = 0; // number of objects in queue
    public final Queue<T> queue = new Queue<>(); // queue object
    private String lastOperation = "";
    private String lastObject = "";
    /**
     *  Queue constructor
     *  Title with empty queue
     */
    public QueueChange(String name) {
        this.name = name;
    }

    public int getCount() {
        return this.count;
    }

    /**
     * Print any array objects from queue
     */
    public void printQueue() {
        System.out.println(lastOperation + ": " + lastObject);
        System.out.print(this.name + " count: " + count);
        System.out.print(", data: ");
        for (T data : queue)
            System.out.print(data + " ");
        System.out.println();
    }

    public void printIntQueue() {
        for (T data : queue)
        System.out.print(data + " ");
        System.out.println();
    }

    /**
     * Add an objects to queue
     */
    public void add(T object) {  //accepts single generic T Object

        this.queue.add(object);
        this.count++;

        this.lastOperation = "Enqueued";
        this.lastObject = object.toString();
    }

    public LinkedList<T> getHead() {
        return this.queue.getHead();
    }

    public T delete() {  //accepts single generic T Object
        T headObject = this.queue.delete();
        this.count--;

        this.lastOperation = "Dequeued";
        this.lastObject = headObject.toString();

        return headObject;
    }

    public T peek() {  //accepts single generic T Object
        return this.queue.peek();
    }

    public LinkedList<T> getNode(int index) {
        LinkedList<T> node = queue.getHead();
        for (int i = 0; i < index; i++) {
            node = node.getNext();
        }
        return node;
    }

    public void shuffle() {

        for(LinkedList<T> node1 = queue.getHead(); node1 != null; node1 = node1.getNext()) {
            Random random = new Random();
            int index = random.nextInt(count);
            
            LinkedList<T> node2 = getNode(index);

            T temp = node1.getData();
            node1.setData(node2.getData());
            node2.setData(temp);
      
          }
    }
}

Challenge #1

class QueueChangeTester {
    public static void main(String[] args) {
        Object[] words = new String[] { "seven", "slimy", "snakes", "sallying", "slowly", "slithered", "southward"};
        QueueChange qWords = new QueueChange("Words");

        for (Object o : words) {
            qWords.add(o);
            qWords.printQueue();
        }

        for (Object o : words) {
            qWords.delete();
            qWords.printQueue();
        }

        Object[] FRQs = new String[] { "2021 Question 1", "2019 Question 2", "2020 Question 3", "2003 Question 4", "2016 Question 3", "2018 Question 2", "2005 Question 1"};
        QueueChange qFRQs = new QueueChange("FRQs");

        for (Object o : FRQs) {
            qFRQs.add(o);
            qFRQs.printQueue();
        }

        for (Object o : FRQs) {
            qFRQs.delete();
            qFRQs.printQueue();
        }
    }
}
QueueChangeTester.main(null);
Enqueued: seven
Words count: 1, data: seven 
Enqueued: slimy
Words count: 2, data: seven slimy 
Enqueued: snakes
Words count: 3, data: seven slimy snakes 
Enqueued: sallying
Words count: 4, data: seven slimy snakes sallying 
Enqueued: slowly
Words count: 5, data: seven slimy snakes sallying slowly 
Enqueued: slithered
Words count: 6, data: seven slimy snakes sallying slowly slithered 
Enqueued: southward
Words count: 7, data: seven slimy snakes sallying slowly slithered southward 
Dequeued: seven
Words count: 6, data: slimy snakes sallying slowly slithered southward 
Dequeued: slimy
Words count: 5, data: snakes sallying slowly slithered southward 
Dequeued: snakes
Words count: 4, data: sallying slowly slithered southward 
Dequeued: sallying
Words count: 3, data: slowly slithered southward 
Dequeued: slowly
Words count: 2, data: slithered southward 
Dequeued: slithered
Words count: 1, data: southward 
Dequeued: southward
Words count: 0, data: 
Enqueued: 2021 Question 1
FRQs count: 1, data: 2021 Question 1 
Enqueued: 2019 Question 2
FRQs count: 2, data: 2021 Question 1 2019 Question 2 
Enqueued: 2020 Question 3
FRQs count: 3, data: 2021 Question 1 2019 Question 2 2020 Question 3 
Enqueued: 2003 Question 4
FRQs count: 4, data: 2021 Question 1 2019 Question 2 2020 Question 3 2003 Question 4 
Enqueued: 2016 Question 3
FRQs count: 5, data: 2021 Question 1 2019 Question 2 2020 Question 3 2003 Question 4 2016 Question 3 
Enqueued: 2018 Question 2
FRQs count: 6, data: 2021 Question 1 2019 Question 2 2020 Question 3 2003 Question 4 2016 Question 3 2018 Question 2 
Enqueued: 2005 Question 1
FRQs count: 7, data: 2021 Question 1 2019 Question 2 2020 Question 3 2003 Question 4 2016 Question 3 2018 Question 2 2005 Question 1 
Dequeued: 2021 Question 1
FRQs count: 6, data: 2019 Question 2 2020 Question 3 2003 Question 4 2016 Question 3 2018 Question 2 2005 Question 1 
Dequeued: 2019 Question 2
FRQs count: 5, data: 2020 Question 3 2003 Question 4 2016 Question 3 2018 Question 2 2005 Question 1 
Dequeued: 2020 Question 3
FRQs count: 4, data: 2003 Question 4 2016 Question 3 2018 Question 2 2005 Question 1 
Dequeued: 2003 Question 4
FRQs count: 3, data: 2016 Question 3 2018 Question 2 2005 Question 1 
Dequeued: 2016 Question 3
FRQs count: 2, data: 2018 Question 2 2005 Question 1 
Dequeued: 2018 Question 2
FRQs count: 1, data: 2005 Question 1 
Dequeued: 2005 Question 1
FRQs count: 0, data: 

Challenge #2

class QueueRearrange {
    public static void main(String[] args) {
    

        Object[] ints1 = new Integer[] { 1, 3, 5, 7};
        QueueChange q1 = new QueueChange("Queue1");
        Object[] ints2 = new Integer[] { 2, 4, 6, 8};
        QueueChange q2 = new QueueChange("Queue2");
        Object[] ints3 = new Integer[] { };
        QueueChange q3 = new QueueChange("Queue3");

        for (Object o : ints1) {
            q1.add(o);
        }
        for (Object o : ints2) {
            q2.add(o);
        }
        
        System.out.print("Initial Queue First: "); 
        q1.printIntQueue();
        System.out.print("Initial Queue Second: "); 
        q2.printIntQueue();

        while (q1.getCount() != 0 || q2.getCount() != 0) {
            if (q1.getCount() != 0 && q2.getCount() != 0) {
                int i1 = (Integer) q1.peek();
                int i2 = (Integer) q2.peek();
                    if (i1 <= i2) {
                        q3.add(q1.delete());
                    }
                    else {
                        q3.add(q2.delete());
                    }
            }
            else if (q1.getCount() != 0) {
                q3.add(q1.delete());
            } 
            else if (q2.getCount() !=0) {
                q3.add(q2.delete());
            }
            else {

            }
        }
        System.out.print("Final Queue Third: "); 
        q3.printIntQueue();
    }
}
QueueRearrange.main(null);
Initial Queue First: 1 3 5 7 
Initial Queue Second: 2 4 6 8 
Final Queue Third: 1 2 3 4 5 6 7 8 

Challenge #3

public class ShuffleTester {
  public static void main(String[] args) { 
    Object[] numbers = new Integer[] { 1, 2, 3, 4, 5};
    QueueChange qNumbers = new QueueChange("Numbers");

        for (Object o : numbers) {
          qNumbers.add(o);
        }

      System.out.print("Original Queue: ");
      qNumbers.printIntQueue();
      qNumbers.shuffle();
      System.out.print("Queue After Shuffling: ");
      qNumbers.printIntQueue();
      

  }
}
ShuffleTester.main(null);
Original Queue: 1 2 3 4 5 
Queue After Shuffling: 1 2 3 5 4 

Challenge #4

import java.util.Stack;

public class QueueToStackExample {
    public static void main(String[] args) {
    Object[] numbers = new Integer[] { 1, 2, 3, 4, 5};
    QueueChange qNumbers = new QueueChange("Numbers");

        for (Object o : numbers) {
          qNumbers.add(o);
        }

    Stack<Object> stack = new Stack<>();

    System.out.println("Stack Initial: " + stack);
    System.out.print("Queue Initial: ");
    qNumbers.printIntQueue();

    // Add integers 1 through 5 to the stack

    int count = qNumbers.getCount();
    for (int i = 0; i < count; i++) {
      stack.push(qNumbers.delete());
    }

    System.out.println("Stack Full: " + stack);
    System.out.print("Queue when Stacked: ");
    qNumbers.printIntQueue();

    for (int i = 0; i < count; i++) {
      qNumbers.add(stack.pop());
    }
    
    System.out.println("Stack Final: " + stack);
    System.out.print("Queue Final: ");
    qNumbers.printIntQueue();
    }
}
QueueToStackExample.main(null);
Stack Initial: []
Queue Initial: 1 2 3 4 5 
Stack Full: [1, 2, 3, 4, 5]
Queue when Stacked: 
Stack Final: []
Queue Final: 5 4 3 2 1