diff --git a/SDEV333-Term-Project.iml b/SDEV333-Term-Project.iml
index c90834f..0f07f6c 100644
--- a/SDEV333-Term-Project.iml
+++ b/SDEV333-Term-Project.iml
@@ -4,8 +4,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Bag/Bag.java b/src/Bag/Bag.java
new file mode 100644
index 0000000..4acb2e4
--- /dev/null
+++ b/src/Bag/Bag.java
@@ -0,0 +1,26 @@
+package Bag;
+
+/**
+ * An implementation of the Bag data structure
+ * @param Class may store various types of values
+ * @author Zalman I.
+ */
+public interface Bag extends Iterable {
+ /**
+ * Adds the given item to the bag
+ * @param item the item to be added
+ */
+ void add(E item);
+
+ /**
+ * Checks whether the bag is empty, and returns true/false accordingly
+ * @return true if the bag is empty; otherwise false
+ */
+ boolean isEmpty();
+
+ /**
+ * Gets and returns the number of items stored in the bag
+ * @return the number of items stored in the bag
+ */
+ int size();
+}
\ No newline at end of file
diff --git a/src/Bag/LinkedBag.java b/src/Bag/LinkedBag.java
new file mode 100644
index 0000000..7aa66a1
--- /dev/null
+++ b/src/Bag/LinkedBag.java
@@ -0,0 +1,169 @@
+package Bag;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Implementation of a Bag using a "list" of nodes and a Bag interface for generics
+ * @param Class may store various types of values
+ * @author Zalman I.
+ */
+public class LinkedBag implements Bag {
+ /**
+ * A container which contains an item and a connection to another Node
+ */
+ private class Node {
+ /**
+ * The item stored within the Node
+ */
+ E item;
+
+ /**
+ * The node this Node is pointing to
+ */
+ Node next;
+
+ /**
+ * Creates a node, and stores the given item within it
+ *
+ * Runtime: O(1) as it always takes the same runtime to conduct this operation
+ *
+ * @param item the item being stored in node
+ */
+ public Node(E item) {
+ // store given item
+ this.item = item;
+
+ // node starts off disconnected
+ next = null;
+ }
+ }
+
+ /**
+ * The first node in bag
+ */
+ private Node first;
+
+ /**
+ * The number of items stored in this bag
+ */
+ private int size;
+
+ /**
+ * Constructs an empty LinkedBag
+ *
+ * Runtime: O(1) as it always takes the same runtime to conduct this operation
+ */
+ public LinkedBag() {
+ // bag starts off empty
+ first = null;
+ size = 0;
+ }
+
+ /**
+ * Adds the given item to the bag
+ *
+ * Runtime: O(1) as we can instantly add a new item to start of list via the first variable,
+ * regardless of how many nodes exist in bag.
+ *
+ * @param item the item to be added
+ */
+ @Override
+ public void add(E item) {
+ // create new node containing given item
+ Node newNode = new Node(item);
+
+ // if the bag is not empty
+ if(!isEmpty()) {
+ // point new node at first, so it isn't lost
+ newNode.next = first;
+ }
+
+ // override first with newly created node
+ // (making new node first node in bag)
+ first = newNode;
+
+ // account for new item in bag
+ size++;
+ }
+
+ /**
+ * Checks whether the bag is empty, and returns true/false accordingly
+ *
+ * Runtime: O(1) as we are instantly accessing variables and checking a condition.
+ * This operation would always take the same runtime to conduct.
+ *
+ * @return true if the bag is empty; otherwise false
+ */
+ @Override
+ public boolean isEmpty() {
+ return size == 0 && first == null;
+ }
+
+ /**
+ * Gets and returns the number of items stored in the bag
+ *
+ * Runtime: O(1) as we are instantly retrieving a variable.
+ * This operation would always take the same runtime to conduct.
+ *
+ * @return the number of items stored in the bag
+ */
+ @Override
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Returns an iterator over elements of type {@code T}.
+ *
+ * @return an Iterator.
+ */
+ @Override
+ public Iterator iterator() {
+ return new LinkedBagIterator();
+ }
+
+ /**
+ * Implementation of an Iterator for the LinkedBag class
+ */
+ private class LinkedBagIterator implements Iterator
+ {
+ /**
+ * The current Node being tracked by the Iterator
+ */
+ private Node current;
+
+ /**
+ * Constructs a LinkedBag iterator, with the first node tracked first
+ */
+ LinkedBagIterator() {
+ current = first;
+ }
+
+ /**
+ * Checks if list contains another element, and returns true/false accordingly
+ * @return true if list contains another element; otherwise false
+ */
+ public boolean hasNext() {
+ return current != null;
+ }
+
+ /**
+ * Gets and returns the first item in the list
+ * @return the first item in the list
+ */
+ public E next() {
+ if(!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ // get first item of list
+ E currItem = current.item;
+
+ // move on to the next item
+ current = current.next;
+
+ return currItem;
+ }
+ }
+}
diff --git a/src/Bag/Stats.java b/src/Bag/Stats.java
new file mode 100644
index 0000000..31a8df3
--- /dev/null
+++ b/src/Bag/Stats.java
@@ -0,0 +1,44 @@
+package Bag;
+
+import java.util.Scanner;
+
+public class Stats
+{
+ public static void main(String[] args) {
+ // setup storage bag
+ Bag numbers = new LinkedBag();
+
+ // setup scanner, taking in given string
+ Scanner line = new Scanner("100 99 101 120 98 107 109 81 101 90");
+
+ // run through line
+ while (line.hasNextDouble()) {
+ // get current item and add to bag
+ numbers.add(line.nextDouble());
+ }
+
+ // track number of items in bag
+ int size = numbers.size();
+
+ // run through bag and add up all items
+ double sum = 0.0;
+ for (double currNum : numbers) {
+ sum += currNum;
+ }
+
+ // get the mean of all numbers in bag
+ double mean = sum / size;
+
+ // clear total tracker and use again to calculate standard dev
+ sum = 0.0;
+ for (double currNum : numbers) {
+ sum += (currNum - mean) * (currNum - mean);
+ }
+
+ double std = Math.sqrt(sum / (size - 1));
+
+ // display calculation results
+ System.out.printf("Mean: %.2f\n", mean);
+ System.out.printf("Std dev: %.2f\n", std);
+ }
+}
\ No newline at end of file
diff --git a/src/Deque.java b/src/Examples/Deque.java
similarity index 97%
rename from src/Deque.java
rename to src/Examples/Deque.java
index 0107f47..a4d7714 100644
--- a/src/Deque.java
+++ b/src/Examples/Deque.java
@@ -1,3 +1,5 @@
+package Examples;
+
/**
* Deque: double-ended queue API
* Supports adding and removing items at both ends.
diff --git a/src/MathSet.java b/src/Examples/MathSet.java
similarity index 99%
rename from src/MathSet.java
rename to src/Examples/MathSet.java
index 5b87e0d..d5b6ea0 100644
--- a/src/MathSet.java
+++ b/src/Examples/MathSet.java
@@ -1,3 +1,5 @@
+package Examples;
+
/**
* MathSet API (interface / abstract data type)
* represents a mathematical set. Sets in mathematics
diff --git a/src/List/ArrayList.java b/src/List/ArrayList.java
new file mode 100644
index 0000000..0f9db11
--- /dev/null
+++ b/src/List/ArrayList.java
@@ -0,0 +1,447 @@
+package List;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Implementation of an ArrayList using the List interface for generics
+ * @param Class may store various types of values
+ * @author Zalman I.
+ */
+public class ArrayList implements List {
+ /**
+ * An array used to store items placed within the ArrayList
+ */
+ private E[] buffer;
+
+ /**
+ * The number of items stored within buffer
+ */
+ private int size;
+
+ /**
+ * Constructs an ArrayList with an empty buffer, and a default max capacity of 10 items
+ *
+ * Runtime: O(1) as it always takes the same runtime to conduct this operation
+ */
+ public ArrayList() {
+ // setup buffer with default max capacity of 10
+ buffer = (E[]) new Object[10];
+
+ // no items are stored in buffer
+ size = 0;
+ }
+
+ /**
+ * If all slots in buffer are full, double its max capacity
+ *
+ * Runtime: O(n) as it has to run through the buffer to copy over all items into a new array,
+ * therefore the runtime depends on the prior buffer's length
+ */
+ private void doubleMaxCapacity() {
+ // if all buffer slots are filled
+ if(size == buffer.length) {
+ // create a new buffer, with double the capacity of the existing buffer
+ E[] newBuffer = (E[]) new Object[size * 2];
+
+ // run through previous buffer and copy over all items
+ for(int i = 0; i < buffer.length; i++) {
+ newBuffer[i] = buffer[i];
+ }
+
+ // replace buffer with newBuffer, now with double the length
+ buffer = newBuffer;
+ }
+ }
+
+ /**
+ * Add item to the front.
+ *
+ * Runtime: O(1) in the case that buffer is empty, as only storage at index 0 occurs.
+ * Otherwise O(n) as the runtime depends on the number of items already in the list. If we need to resize,
+ * the buffer gets run through to copy over items. If not, we are still shifting over all existing items to the right.
+ *
+ * @param item the item to be added
+ */
+ @Override
+ public void addFront(E item) {
+ // if the buffer already contains items
+ if(!isEmpty()) {
+ // if the buffer is full, increase max capacity
+ doubleMaxCapacity(); // O(n)
+
+ // run through buffer backwards
+ for (int i = size; i > 0; i--) {
+ // get item at previous index and place in current index,
+ // thereby shifting all items to the left
+ buffer[i] = buffer[i - 1];
+ }
+ }
+
+ // add the given item at the now cleared index 0
+ buffer[0] = item;
+
+ // a new item has been added to buffer
+ size++;
+ }
+
+ /**
+ * Add item to the back.
+ *
+ * Runtime: O(1) if buffer is empty/not full, as we are only accessing the final index to add an item.
+ * If the array is full O(n) as we need to run through buffer to copy over all items during resize.
+ *
+ * @param item the item to be added
+ */
+ @Override
+ public void addBack(E item) {
+ // if the buffer is full, increase max capacity
+ doubleMaxCapacity();
+
+ // add the given item at final index
+ buffer[size] = item;
+
+ // a new item has been added to buffer
+ size++;
+ }
+
+ /**
+ * Add an item at specified index (position).
+ *
+ * Runtime: O(1) if the array is empty. Otherwise, O(n) as runtime will depend on array size,
+ * either for resizing or shifting over items to free up given index
+ *
+ * @param index the index where the item should be added
+ * @param item the item to be added
+ */
+ @Override
+ public void add(int index, E item) {
+ // if the given index is out of range
+ if(index < 0 || index > size) {
+ throw new IndexOutOfBoundsException(index + " is not a valid index");
+ }
+
+ // if the buffer is full, increase max capacity
+ doubleMaxCapacity();
+
+ // run through buffer backwards, up to given index
+ for (int i = size; i > index; i--) {
+ // get item at previous index and place in current index,
+ // thereby shifting all items to the right
+ buffer[i] = buffer[i - 1];
+ }
+
+ // add the given item at current index
+ buffer[index] = item;
+
+ // a new item has been added to buffer
+ size++;
+ }
+
+ /**
+ * Get the item at a specified index.
+ *
+ * Runtime: O(1) as we can instantly access the given index to retrieve item,
+ * assuming index exists/buffer not empty.
+ *
+ * @param index the index where the item should be retrieved
+ * @return the item located at that index
+ */
+ @Override
+ public E get(int index) {
+ // if the given index is out of range
+ if(index < 0 || index > size) {
+ throw new IndexOutOfBoundsException(index + " is not a valid index");
+ }
+
+ // if buffer contains no items, one cannot be retrieved
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot retrieve item from empty List.ArrayList");
+ }
+
+ return buffer[index];
+ }
+
+ /**
+ * Set (save) an item at a specified index. Previous
+ * item at that index is overwritten.
+ *
+ * Runtime: O(1) as we can instantly access the given index to replace its item,
+ * assuming index exists/buffer not empty.
+ *
+ * @param index the index where the item should be saved
+ * @param item the item to be saved
+ */
+ @Override
+ public void set(int index, E item) {
+ // if the given index is out of range
+ if(index < 0 || index > size) {
+ throw new IndexOutOfBoundsException(index + " is not a valid index");
+ }
+
+ // place the given item at the requested index
+ buffer[index] = item;
+
+ // if the buffer is regarded as empty, account for new item placed at index 0
+ if(isEmpty()) {
+ size++;
+ }
+ }
+
+ /**
+ * Remove item at the front of the list.
+ *
+ * Runtime: O(n) as we are shifting over all items in buffer left to "remove" the item at index 0.
+ *
+ * @return the item that was removed
+ */
+ @Override
+ public E removeFront() {
+ // if buffer contains no items, one cannot be removed
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot remove item from empty ArrayList");
+ }
+
+ // get requested item prior to removal
+ E requestedItem = buffer[0];
+
+ // run through buffer
+ for(int i = 0; i < size; i++) {
+ // replace item at current index with item at next index
+ buffer[i] = buffer[i + 1];
+ }
+
+ // account for removal of item
+ size--;
+
+ return requestedItem;
+ }
+
+ /**
+ * Remove item at the back of the list
+ *
+ * Runtime: O(1) as we can instantly access the final index and set its value to null.
+ *
+ * @return the item that was removed
+ */
+ @Override
+ public E removeBack() {
+ // if buffer contains no items, one cannot be removed
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot remove item from empty ArrayList");
+ }
+
+ // get requested item prior to removal, accounting for index
+ E requestedItem = buffer[size - 1];
+
+ // clear the final item in buffer
+ buffer[size - 1] = null;
+
+ // account for removal of item
+ size--;
+
+ return requestedItem;
+ }
+
+ /**
+ * Remove item from the list
+ *
+ * Runtime: O(n) as searching for the given item via indexOf results in running through buffer once.
+ * If searching reveals it exists, we then also have to shift over all items after it left to remove it.
+ *
+ * @param item the item to be removed
+ */
+ @Override
+ public void remove(E item) {
+ // if buffer contains no items, one cannot be removed
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot remove item from empty ArrayList");
+ }
+
+ // find item in buffer and get its index
+ int index = indexOf(item); // O(n)
+
+ // if item is not in buffer
+ if(index == -1) {
+ throw new NoSuchElementException("Given item is not located in ArrayList");
+ }
+
+ // otherwise, run through buffer, starting at given index
+ // and accounting for removal of requested item
+ for(int i = index; i <= size - 1; i++) {
+ // replace item at current index with item at next index
+ buffer[i] = buffer[i + 1];
+ }
+
+ // account for removal of item
+ size--;
+ }
+
+ /**
+ * Gets and returns the index of the given item in buffer, if exists
+ *
+ * Runtime: O(n) as we could potentially run through the entire buffer when searching for the given item.
+ *
+ * @param item the item being searched for in buffer
+ * @return the index of given item in buffer if exists; otherwise -1
+ */
+ private int indexOf(E item) {
+ // run through buffer
+ for(int i = 0; i < buffer.length; i++) {
+ // check if item stored at current index is the specified item
+ if(item.equals(buffer[i])) {
+ // return the current index, as that is where the specified item is located
+ return i;
+ }
+ }
+
+ // if the item does not exist in buffer
+ return -1;
+ }
+
+ /**
+ * Remove item at a specified index.
+ *
+ * Runtime: O(n) as runtime will depend on the number of items after given index which we need to shift left.
+ *
+ * @param index the index where the item should be removed
+ * @return the item that was removed
+ */
+ @Override
+ public E remove(int index) {
+ // if the given index is out of range
+ if(index < 0 || index > size) {
+ throw new IndexOutOfBoundsException(index + " is not a valid index");
+ }
+
+ // if buffer contains no items, one cannot be removed
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot remove item from empty ArrayList");
+ }
+
+ // get requested item prior to removal
+ E requestedItem = buffer[index];
+
+ // run through buffer, starting at given index
+ // and accounting for removal of requested item
+ for(int i = index; i <= size - 1; i++) {
+ // replace item at current index with item at next index
+ buffer[i] = buffer[i + 1];
+ }
+
+ // account for removal of item
+ size--;
+
+ return requestedItem;
+ }
+
+ /**
+ * Checks if an item is in the list.
+ *
+ * Runtime O(n) as searching for the item requires running through buffer, and depends on its location
+ * within/number of items before and after it.
+ *
+ * @param item the item to search for
+ * @return true if the item is in the list, false otherwise
+ */
+ @Override
+ public boolean contains(E item) {
+ // run through buffer
+ for (int i = 0; i < size; i++) {
+ // check if item at current index of buffer is given item
+ if(item.equals(buffer[i])) {
+ // item was located
+ return true;
+ }
+ }
+
+ // item could not be found
+ return false;
+ }
+
+ /**
+ * Checks if the list is empty.
+ *
+ * Runtime: O(1) as we are instantly accessing a variable and checking a condition.
+ * This operation would always take the same runtime to conduct.
+ *
+ * @return true if the list is empty, false otherwise
+ */
+ @Override
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ /**
+ * Provides a count of the number of items in the list.
+ *
+ * Runtime: O(1) as we are instantly retrieving a variable.
+ * This operation would always take the same runtime to conduct.
+ *
+ * @return number of items in the list
+ */
+ @Override
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Returns an iterator over elements of type {@code T}.
+ *
+ * @return an Iterator.
+ */
+ @Override
+ public Iterator iterator() {
+ return new ArrayListIterator();
+ }
+
+ /**
+ * Implementation of an Iterator for the ArrayIntList class
+ */
+ private class ArrayListIterator implements Iterator {
+ /**
+ * The current index being tracked by the Iterator
+ */
+ private int index;
+
+ /**
+ * Constructs an ArrayIntList iterator with the index initialized to 0
+ */
+ ArrayListIterator() {
+ index = 0;
+ }
+
+ /**
+ * Returns {@code true} if the iteration has more elements.
+ * (In other words, returns {@code true} if {@link #next} would
+ * return an element rather than throwing an exception.)
+ *
+ * @return {@code true} if the iteration has more elements
+ */
+ @Override
+ public boolean hasNext() {
+ return index < size;
+ }
+
+ /**
+ * Returns the next element in the iteration.
+ *
+ * @return the next element in the iteration
+ * @throws NoSuchElementException if the iteration has no more elements
+ */
+ @Override
+ public E next() {
+ if(!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ // get the item at current index of buffer
+ E currItem = buffer[index];
+
+ // move on to next element
+ index++;
+
+ return currItem;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/List/LinkedList.java b/src/List/LinkedList.java
new file mode 100644
index 0000000..d828a26
--- /dev/null
+++ b/src/List/LinkedList.java
@@ -0,0 +1,531 @@
+package List;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Implementation of a LinkedList using the List interface for generics
+ * @param Class may store various types of values
+ * @author Zalman I.
+ */
+public class LinkedList implements List {
+ /**
+ * A container which contains an item and a connection to another Node
+ */
+ private class Node {
+ /**
+ * The item stored within the Node
+ */
+ E item;
+
+ /**
+ * The node this Node is pointing to
+ */
+ Node next;
+
+ /**
+ * Creates a node, and stores the given item within it
+ *
+ * Runtime: O(1) as it always takes the same runtime to conduct this operation
+ *
+ * @param item the item being stored in node
+ */
+ public Node(E item) {
+ // store given item
+ this.item = item;
+
+ // node starts off disconnected
+ next = null;
+ }
+ }
+
+ /**
+ * The first Node of the current LinkedList
+ */
+ private Node head;
+
+ /**
+ * The number of items stored in this LinkedList
+ */
+ private int size;
+
+ /**
+ * Constructs an empty LinkedList
+ *
+ * Runtime: O(1) as it always takes the same runtime to conduct this operation
+ */
+ public LinkedList() {
+ // list starts off empty
+ head = null;
+ size = 0;
+ }
+
+ /**
+ * Add item to the front.
+ *
+ * Runtime: O(1) as we can quickly access the front of list via the head variable,
+ * regardless of how many nodes follow it.
+ *
+ * @param item the item to be added
+ */
+ @Override
+ public void addFront(E item) {
+ // create new node containing given item
+ Node newNode = new Node(item);
+
+ // if the list is not empty
+ if(!isEmpty()) {
+ // point new node at head
+ newNode.next = head;
+ }
+
+ // override head with newly created node
+ // (making new node first node in list)
+ head = newNode;
+
+ // account for new item in list
+ size++;
+ }
+
+ /**
+ * Add item to the back.
+ *
+ * Runtime: O(1) if the list is empty. Otherwise, O(n), as runtime depends on the number of nodes already
+ * in list we need to pass to reach the end.
+ *
+ * @param item the item to be added
+ */
+ @Override
+ public void addBack(E item) {
+ // if list is empty
+ if(isEmpty()) {
+ // add item at front of list
+ addFront(item);
+ }
+
+ // if list is not empty
+ else {
+ // create new node containing given item
+ Node newNode = new Node(item);
+
+ // setup tracker and run to end of list
+ Node current = head;
+
+ while(current.next != null) {
+ current = current.next;
+ }
+
+ // point final node at new node
+ current.next = newNode;
+
+ // account for new item in list
+ size++;
+ }
+ }
+
+ /**
+ * Add an item at specified index (position).
+ *
+ * Runtime: O(1) if the given index is 0 as we use the addFront method.
+ * Otherwise O(n) as we may potentially have to traverse all the way to middle or end of list.
+ *
+ * @param index the index where the item should be added
+ * @param item the item to be added
+ */
+ @Override
+ public void add(int index, E item) {
+ // if given index is out of range
+ if(index < 0 || index > size) {
+ throw new IndexOutOfBoundsException(index + " is not a valid index");
+ }
+
+ // if given index was at front or back, use those methods
+ else if(index == 0) {
+ addFront(item); // O(1)
+ }
+
+ else if(index == size) {
+ addBack(item); // O(n)
+ }
+
+ else {
+ // setup trackers
+ Node previous = null;
+ Node current = head;
+ int currIndex = 0;
+
+ // run through list, up to given index
+ while(current != null && currIndex != index) {
+ // update trackers
+ previous = current;
+ current = current.next;
+ currIndex++;
+ }
+
+ // place given item in new node
+ Node newNode = new Node(item);
+
+ // update links of previous and current nodes to account for new node
+ previous.next = newNode;
+ newNode.next = current;
+
+ // account for new item in list
+ size++;
+ }
+ }
+
+ /**
+ * Get the item at a specified index.
+ *
+ * Runtime: O(n) as runtime will depend on how many nodes we need to pass in list to reach the requested index.
+ *
+ * @param index the index where the item should be retrieved
+ * @return the item located at that index
+ */
+ @Override
+ public E get(int index) {
+ // if given index is out of range
+ if(index < 0 || index > size) {
+ throw new IndexOutOfBoundsException(index + " is not a valid index");
+ }
+
+ // if list is empty
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot retrieve item from empty LinkedList");
+ }
+
+ // setup trackers
+ int currIndex = 0;
+ Node current = head;
+
+ // run through list, up to given index
+ while(current != null && currIndex != index) {
+ // update trackers
+ current = current.next;
+ currIndex++;
+ }
+
+ // return item at current node/index
+ return current.item;
+ }
+
+ /**
+ * Set (save) an item at a specified index. Previous
+ * item at that index is overwritten.
+ *
+ * Runtime: O(1) if the list is empty as we use the addFront method.
+ * Otherwise, O(n) as runtime will depend on how many nodes we need to pass in list to reach the requested index.
+ *
+ * @param index the index where the item should be saved
+ * @param item the item to be saved
+ */
+ @Override
+ public void set(int index, E item) {
+ // if the given index is out of range
+ if(index < 0 || index > size) {
+ throw new IndexOutOfBoundsException(index + " is not a valid index");
+ }
+
+ // if list is empty
+ if(isEmpty()) {
+ // add given item to list at front
+ addFront(item);
+ }
+
+ else {
+ // setup trackers
+ int currIndex = 0;
+ Node current = head;
+
+ // run through list, up to given index
+ while (current != null && currIndex != index) {
+ // update trackers
+ current = current.next;
+ currIndex++;
+ }
+
+ // overwrite item in current node with given item
+ current.item = item;
+ }
+ }
+
+ /**
+ * Remove item at the front of the list.
+ *
+ * Runtime: O(1) as we can quickly access the front of list via the head variable,
+ * regardless of how many nodes follow it.
+ *
+ * @return the item that was removed
+ */
+ @Override
+ public E removeFront() {
+ // if list contains no items, one cannot be removed
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot remove item from empty LinkedList");
+ }
+
+ // get requested item from head
+ E requestedItem = head.item;
+
+ // overwrite head with next item in sequence,
+ // if no next item, head will become null
+ head = head.next;
+
+ // account for element removal
+ size--;
+
+ return requestedItem;
+ }
+
+ /**
+ * Remove item at the back of the list
+ *
+ * Runtime: O(n), as runtime depends on the number of nodes already in list we need to pass to reach the end.
+ *
+ * @return the item that was removed
+ */
+ @Override
+ public E removeBack() {
+ // if list contains no items, one cannot be removed
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot remove item from empty LinkedList");
+ }
+
+ // setup trackers and run through list till second to last node
+ Node current = head;
+
+ while(current.next.next != null) {
+ current = current.next;
+ }
+
+ // get requested item from final node
+ E requestedItem = current.next.item;
+
+ // update current node to stop tracking final node
+ current.next = null;
+
+ // account for item removal
+ size--;
+
+ return requestedItem;
+ }
+
+ /**
+ * Remove item from the list
+ *
+ * Runtime: O(n) as we use the contains method to check if item exists, which may require running through entire list.
+ * If it does exist, we then use the remove method, which in the worse case also runs at O(n).
+ *
+ * @param item the item to be removed
+ */
+ @Override
+ public void remove(E item) {
+ // if list contains no items, one cannot be removed
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot remove item from empty LinkedList");
+ }
+
+ // check if list contains given item - O(n)
+ if(!contains(item)) {
+ throw new NoSuchElementException("Given item is not located in LinkedList");
+ }
+
+ // setup trackers and flag
+ Node current = head;
+ int currIndex = 0;
+ boolean itemNotFound = true;
+
+ // run through list until item is found
+ while(current != null && itemNotFound) {
+ // check if the current node contains given item
+ if(item.equals(current.item)) {
+ // call the other remove method on current index
+ remove(currIndex);
+
+ // cease loop, item was found and removed
+ itemNotFound = false;
+ }
+
+ // update trackers
+ current = current.next;
+ currIndex++;
+ }
+ }
+
+ /**
+ * Remove item at a specified index.
+ *
+ * Runtime: O(1) if the given index is 0 as we use the addFront method.
+ * Otherwise, O(n) as we may potentially have to traverse all the way to middle or end of list to unlink a node.
+ *
+ * @param index the index where the item should be removed
+ * @return the item that was removed
+ */
+ @Override
+ public E remove(int index) {
+ // if the given index is out of range
+ if(index < 0 || index > size) {
+ throw new IndexOutOfBoundsException(index + " is not a valid index");
+ }
+
+ // if list contains no items, one cannot be removed
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot remove item from empty LinkedList");
+ }
+
+ // if given index was at front or back, use those methods
+ else if(index == 0) {
+ return removeFront();
+ }
+
+ else if(index == size) {
+ return removeBack();
+ }
+
+ else {
+ // setup trackers
+ Node previous = null;
+ Node current = head;
+ int currIndex = 0;
+
+ // run through list, up to given index
+ while(current != null && currIndex != index) {
+ // update trackers
+ previous = current;
+ current = current.next;
+ currIndex++;
+ }
+
+ // get item stored in node at current index
+ E requestedItem = current.item;
+
+ // point previous node at current's next node,
+ // thereby cutting out current
+ previous.next = current.next;
+
+ // account for removal of item
+ size--;
+
+ return requestedItem;
+ }
+ }
+
+ /**
+ * Checks if an item is in the list.
+ *
+ * Runtime: O(n) as searching for the item may require running through most of, or the entire list
+ *
+ * @param item the item to search for
+ * @return true if the item is in the list, false otherwise
+ */
+ @Override
+ public boolean contains(E item) {
+ // if list is not empty
+ if(!isEmpty()) {
+ // setup pointer
+ Node current = head;
+
+ // run through list
+ while (current != null) {
+ // check if the current Node contains given item
+ if (item.equals(current.item)) {
+ // item was found
+ return true;
+ }
+
+ // move on to next node
+ current = current.next;
+ }
+ }
+
+ // item not located in list, or list empty
+ return false;
+ }
+
+ /**
+ * Checks if the list is empty.
+ *
+ * Runtime: O(1) as we are instantly accessing some variables and checking a condition.
+ * This operation would always take the same runtime to conduct.
+ *
+ * @return true if the list is empty, false otherwise
+ */
+ @Override
+ public boolean isEmpty() {
+ return size == 0 && head == null;
+ }
+
+ /**
+ * Provides a count of the number of items in the list.
+ *
+ * Runtime: O(1) as we are instantly retrieving a variable.
+ * This operation would always take the same runtime to conduct.
+ *
+ * @return number of items in the list
+ */
+ @Override
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Returns an iterator over elements of type {@code T}.
+ *
+ * @return an Iterator.
+ */
+ @Override
+ public Iterator iterator() {
+ return new LinkedListIterator();
+ }
+
+ /**
+ * Implementation of an Iterator for the LinkedList class
+ */
+ private class LinkedListIterator implements Iterator {
+ /**
+ * The current Node being tracked by the Iterator
+ */
+ private Node current;
+
+ /**
+ * Constructs a LinkedList iterator with the head tracked as the first Node
+ */
+ LinkedListIterator() {
+ current = head;
+ }
+
+ /**
+ * Returns {@code true} if the iteration has more elements.
+ * (In other words, returns {@code true} if {@link #next} would
+ * return an element rather than throwing an exception.)
+ *
+ * @return {@code true} if the iteration has more elements
+ */
+ @Override
+ public boolean hasNext() {
+ return current != null;
+ }
+
+ /**
+ * Returns the next element in the iteration.
+ *
+ * @return the next element in the iteration
+ * @throws NoSuchElementException if the iteration has no more elements
+ */
+ @Override
+ public E next() {
+ if(!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ // get the item stored in current node
+ E currItem = current.item;
+
+ // move on to the next node
+ current = current.next;
+
+ // return the current item
+ return currItem;
+ }
+ }
+}
diff --git a/src/List.java b/src/List/List.java
similarity index 96%
rename from src/List.java
rename to src/List/List.java
index 2bf4aef..cdf12a6 100644
--- a/src/List.java
+++ b/src/List/List.java
@@ -1,5 +1,7 @@
+package List;
+
/***
- * List interface (API / abstract data type)
+ * List.List interface (API / abstract data type)
* @param Class or data type of the items in the list.
*/
public interface List extends Iterable {
diff --git a/src/Main.java b/src/Main.java
deleted file mode 100644
index 8f8f984..0000000
--- a/src/Main.java
+++ /dev/null
@@ -1,10 +0,0 @@
-//TIP To Run code, press or
-// click the icon in the gutter.
-public class Main {
- public static void main(String[] args) {
- //TIP Press with your caret at the highlighted text
- // to see how IntelliJ IDEA suggests fixing it.
- System.out.println("Hello and welcome!");
-
- }
-}
\ No newline at end of file
diff --git a/src/Queue/LinkedQueue.java b/src/Queue/LinkedQueue.java
new file mode 100644
index 0000000..a7acfda
--- /dev/null
+++ b/src/Queue/LinkedQueue.java
@@ -0,0 +1,215 @@
+package Queue;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Implementation of a Queue using a "list" of nodes and a Queue interface for generics
+ *
+ * @param Class may store various types of values
+ * @author Zalman I.
+ */
+public class LinkedQueue implements Queue {
+ /**
+ * A container which contains an item and a connection to another Node
+ */
+ private class Node {
+ /**
+ * The item stored within the Node
+ */
+ E item;
+
+ /**
+ * The node this Node is pointing to
+ */
+ Node next;
+
+ /**
+ * Creates a node, and stores the given item within it
+ *
+ * Runtime: O(1) as it always takes the same runtime to conduct this operation
+ *
+ * @param item the item being stored in node
+ */
+ public Node(E item) {
+ // store given item
+ this.item = item;
+
+ // node starts off disconnected
+ next = null;
+ }
+ }
+
+ /**
+ * The front of the queue (least recently added node)
+ */
+ private Node front;
+
+ /**
+ * The back of the queue (most recently added node)
+ */
+ private Node back;
+
+ /**
+ * The number of items stored in this stack
+ */
+ private int size;
+
+ /**
+ * Constructs an empty LinkedStack
+ *
+ * Runtime: O(1) as it always takes the same runtime to conduct this operation
+ */
+ public LinkedQueue() {
+ // queue starts off empty
+ front = null;
+ back = null;
+ size = 0;
+ }
+
+ /**
+ * Add an item to the queue.
+ *
+ * Runtime: O(1) as we can instantly add a new item to back of queue via the back variable,
+ * regardless of how many nodes exist in list.
+ *
+ * @param item the item to be added
+ */
+ @Override
+ public void enqueue(E item) {
+ // track the item currently at back of queue
+ Node currBack = back;
+
+ // replace back node with new node containing given item
+ back = new Node(item);
+
+ // if the queue is empty
+ if(isEmpty()) {
+ // move back node to front
+ front = back;
+ }
+
+ // if queue is not empty
+ else {
+ // add given item to end of queue
+ currBack.next = back;
+ }
+
+ // account for new item in queue
+ size++;
+ }
+
+ /**
+ * Remove an item from the queue.
+ *
+ * Runtime: O(1) as we can instantly access the front variable to retrieve item
+ * and overwrite it with the next node in queue.
+ *
+ * @return the item that was removed
+ */
+ @Override
+ public E dequeue() {
+ // if queue contains no items, one cannot be removed
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot retrieve item from empty Queue");
+ }
+
+ // get requested item from node at front
+ E requestedItem = front.item;
+
+ // overwrite current node at front with next in line
+ // if no more remain, front will become null
+ front = front.next;
+
+ // in the event that queue is now empty and front is null,
+ // overwrite last item
+ if(isEmpty()) {
+ back = null;
+ }
+
+ // account for removal of item from stack
+ size--;
+
+ return requestedItem;
+ }
+
+ /**
+ * Checks to see if the queue is empty.
+ *
+ * Runtime: O(1) as we are instantly accessing variables and checking a condition.
+ * This operation would always take the same runtime to conduct.
+ *
+ * @return true if the queue is empty, false otherwise
+ */
+ @Override
+ public boolean isEmpty() {
+ return size == 0 && front == null;
+ }
+
+ /**
+ * Returns a count of the number of items in the queue.
+ *
+ * Runtime: O(1) as we are instantly retrieving a variable.
+ * This operation would always take the same runtime to conduct.
+ *
+ * @return the number of items in the queue
+ */
+ @Override
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Returns an iterator over elements of type {@code T}.
+ *
+ * @return an Iterator.
+ */
+ @Override
+ public Iterator iterator() {
+ return new LinkedQueueIterator();
+ }
+
+ /**
+ * Implementation of an Iterator for the LinkedQueue class
+ */
+ private class LinkedQueueIterator implements Iterator
+ {
+ /**
+ * The current Node being tracked by the Iterator
+ */
+ private Node current;
+
+ /**
+ * Constructs a LinkedQueue iterator, with the front node tracked first
+ */
+ LinkedQueueIterator() {
+ current = front;
+ }
+
+ /**
+ * Checks if list contains another element, and returns true/false accordingly
+ * @return true if list contains another element; otherwise false
+ */
+ public boolean hasNext() {
+ return current != null;
+ }
+
+ /**
+ * Gets and returns the start/front item in the list
+ * @return the start/front item in the list
+ */
+ public E next() {
+ if(!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ // get item at start/front of list
+ E currItem = current.item;
+
+ // bring the next item over
+ current = current.next;
+
+ return currItem;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Queue.java b/src/Queue/Queue.java
similarity index 91%
rename from src/Queue.java
rename to src/Queue/Queue.java
index ab5ca29..0dbc73b 100644
--- a/src/Queue.java
+++ b/src/Queue/Queue.java
@@ -1,5 +1,7 @@
+package Queue;
+
/**
- * FIFO (first-in, first-out) Queue API
+ * FIFO (first-in, first-out) APIs.Queue API
* @param class / data type of the items in the queue
*/
public interface Queue extends Iterable {
diff --git a/src/Queue/QueueTestClient.java b/src/Queue/QueueTestClient.java
new file mode 100644
index 0000000..06e0904
--- /dev/null
+++ b/src/Queue/QueueTestClient.java
@@ -0,0 +1,35 @@
+package Queue;
+
+import java.util.Scanner;
+
+public class QueueTestClient {
+ public static void main(String[] args) {
+ // setup storage queue
+ Queue storage = new LinkedQueue();
+
+ // setup scanner, taking in given string
+ Scanner line = new Scanner("to be or not to - be - - that - - - is");
+
+ // run through line
+ while (line.hasNext()) {
+ // get current item
+ String item = line.next();
+
+ // if the current item is not a dash
+ if (!item.equals("-")) {
+ // it is a word, add it to queue
+ storage.enqueue(item);
+ System.out.println();
+ }
+
+ // if it is a dash, and the stack is not empty
+ else if (!storage.isEmpty()) {
+ // get the item at front of queue, and display it
+ System.out.println(storage.dequeue());
+ }
+ }
+
+ // display how many items remain in queue at end of line
+ System.out.println("(" + storage.size() + " left in the queue)");
+ }
+}
diff --git a/src/Stack/LinkedStack.java b/src/Stack/LinkedStack.java
new file mode 100644
index 0000000..50e0519
--- /dev/null
+++ b/src/Stack/LinkedStack.java
@@ -0,0 +1,216 @@
+package Stack;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Implementation of a Stack using a "list" of nodes and a Stack interface for generics
+ * @param Class may store various types of values
+ * @author Zalman I.
+ */
+public class LinkedStack implements Stack {
+ /**
+ * A container which contains an item and a connection to another Node
+ */
+ private class Node {
+ /**
+ * The item stored within the Node
+ */
+ E item;
+
+ /**
+ * The node this Node is pointing to
+ */
+ Node next;
+
+ /**
+ * Creates a node, and stores the given item within it
+ *
+ * Runtime: O(1) as it always takes the same runtime to conduct this operation
+ *
+ * @param item the item being stored in node
+ */
+ public Node(E item) {
+ // store given item
+ this.item = item;
+
+ // node starts off disconnected
+ next = null;
+ }
+ }
+
+ /**
+ * The top of the stack (most recently added node)
+ */
+ private Node top;
+
+ /**
+ * The number of items stored in this stack
+ */
+ private int size;
+
+ /**
+ * Constructs an empty LinkedStack
+ *
+ * Runtime: O(1) as it always takes the same runtime to conduct this operation
+ */
+ public LinkedStack() {
+ // stack starts off empty
+ top = null;
+ size = 0;
+ }
+
+ /**
+ * Add an item to the stack.
+ *
+ * Runtime: O(1) as we can instantly add a new item to front/top via the top variable,
+ * regardless of how many nodes exist in stack.
+ *
+ * @param item the item to be added
+ */
+ @Override
+ public void push(E item) {
+ // create new node containing given item
+ Node newNode = new Node(item);
+
+ // if the stack is not empty
+ if(!isEmpty()) {
+ // point new node at top, so it isn't lost
+ newNode.next = top;
+ }
+
+ // override top with newly created node
+ // (making new node first node in stack)
+ top = newNode;
+
+ // account for new item in stack
+ size++;
+ }
+
+ /**
+ * Removes the most recently added item from the stack.
+ *
+ * Runtime: O(1) as we can instantly access the top variable to retrieve item
+ * and overwrite it with the next node in stack.
+ *
+ * @return the item that was removed
+ */
+ @Override
+ public E pop() {
+ // if stack contains no items, one cannot be removed
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot retrieve item from empty Stack");
+ }
+
+ // get requested item from topmost node
+ E requestedItem = top.item;
+
+ // overwrite top with node "under it",
+ // if no more remain, top will become null, making stack empty
+ top = top.next;
+
+ // account for removal of item from stack
+ size--;
+
+ return requestedItem;
+ }
+
+ /**
+ * Returns the item at the top of the stack.
+ * Does not modify the stack or the item at the top.
+ *
+ * Runtime: O(1) as we can instantly access the top variable to retrieve item.
+ *
+ * @return item at the top of the stack.
+ */
+ @Override
+ public E peek() {
+ // if buffer contains no items, one cannot be retrieved
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot retrieve item from empty Stack");
+ }
+
+ // get and return item stored in topmost node
+ return top.item;
+ }
+
+ /**
+ * Checks to see if the stack is empty.
+ *
+ * Runtime: O(1) as we are instantly accessing a variable and checking a condition.
+ * This operation would always take the same runtime to conduct.
+ *
+ * @return true if the stack is empty, false otherwise
+ */
+ @Override
+ public boolean isEmpty() {
+ return top == null && size == 0;
+ }
+
+ /**
+ * Returns a count of the number of items in the stack.
+ *
+ * Runtime: O(1) as we are instantly retrieving a variable.
+ * This operation would always take the same runtime to conduct.
+ *
+ * @return the number of items in the stack
+ */
+ @Override
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Returns an iterator over elements of type {@code T}.
+ *
+ * @return an Iterator.
+ */
+ @Override
+ public Iterator iterator() {
+ return new LinkedStackIterator();
+ }
+
+ /**
+ * Implementation of an Iterator for the LinkedStack class
+ */
+ private class LinkedStackIterator implements Iterator
+ {
+ /**
+ * The current Node being tracked by the Iterator
+ */
+ private Node current;
+
+ /**
+ * Constructs a LinkedStack iterator, with the topmost node tracked first
+ */
+ LinkedStackIterator() {
+ current = top;
+ }
+
+ /**
+ * Checks if list contains another element, and returns true/false accordingly
+ * @return true if list contains another element; otherwise false
+ */
+ public boolean hasNext() {
+ return current != null;
+ }
+
+ /**
+ * Gets and returns the next/top item in the list
+ * @return the next/top item in the list
+ */
+ public E next() {
+ if(!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ // get item at end/top of list
+ E currItem = current.item;
+
+ // move down to the next item
+ current = current.next;
+
+ return currItem;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Stack/ResizingArrayStack.java b/src/Stack/ResizingArrayStack.java
new file mode 100644
index 0000000..9f824a8
--- /dev/null
+++ b/src/Stack/ResizingArrayStack.java
@@ -0,0 +1,211 @@
+package Stack;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Implementation of a Stack using an array and a Stack interface for generics
+ * @param Class may store various types of values
+ * @author Zalman I.
+ */
+public class ResizingArrayStack implements Stack {
+ /**
+ * An array used to store items placed within the stack
+ */
+ private E[] buffer;
+
+ /**
+ * The number of items stored within buffer
+ */
+ private int size;
+
+ /**
+ * Constructs a ResizingArrayStack with an empty buffer,
+ * and a default max capacity of 10 items
+ *
+ * Runtime: O(1) as it always takes the same runtime to conduct this operation
+ */
+ public ResizingArrayStack() {
+ // setup buffer with default max capacity of 10
+ buffer = (E[]) new Object[10];
+
+ // buffer starts off empty
+ size = 0;
+ }
+
+ /**
+ * Resize the buffer by updating its max capacity by given number
+ *
+ * Runtime: O(n) as it has to run through the buffer to copy over all items into a new array,
+ * therefore the runtime depends on the prior buffer's length
+ *
+ * @param maxCapacity the new max capacity of buffer
+ */
+ private void resizeBuffer(int maxCapacity) {
+ // create a new buffer, with the given max capacity
+ E[] newBuffer = (E[]) new Object[maxCapacity];
+
+ // run through current buffer and copy over all items
+ for(int i = 0; i < size; i++) {
+ newBuffer[i] = buffer[i];
+ }
+
+ // override existing buffer with the newly created one,
+ // now with the requested max capacity
+ buffer = newBuffer;
+ }
+
+ /**
+ * Add an item to the stack.
+ *
+ * Runtime: O(1) if buffer is empty/not full, as we are only accessing the final index to add an item.
+ * If the array is full O(n) as we need to run through buffer to copy over all items during resize.
+ *
+ * @param item the item to be added
+ */
+ @Override
+ public void push(E item) {
+ // if the buffer is full, double its max capacity
+ if(size == buffer.length) {
+ resizeBuffer(buffer.length * 2);
+ }
+
+ // add given item to "end/top" of buffer
+ buffer[size] = item;
+
+ // account for new item being added
+ size++;
+ }
+
+ /**
+ * Removes the most recently added item from the stack.
+ *
+ * Runtime: O(1) if buffer is not too large, as we are only accessing the final index to "pop off" an item.
+ * Otherwise, O(n) as we need to run through buffer to copy over all items during resize.
+ *
+ * @return the item that was removed
+ */
+ @Override
+ public E pop() {
+ // if buffer contains no items, one cannot be retrieved
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot retrieve item from empty Stack");
+ }
+
+ // get the end/top item from stack, account for index
+ E requestedItem = buffer[size - 1];
+
+ // clear that slot in buffer
+ buffer[size - 1] = null;
+
+ // account for item being removed
+ size--;
+
+ // if the buffer is not empty, and too large
+ if(size > 0 && size == buffer.length / 4) {
+ // reduce its current max capacity by half
+ resizeBuffer(buffer.length / 2);
+ }
+
+ return requestedItem;
+ }
+
+ /**
+ * Returns the item at the top of the stack.
+ * Does not modify the stack or the item at the top.
+ *
+ * Runtime: O(1) as we can instantly access the final index to retrieve item.
+ *
+ * @return item at the top of the stack.
+ */
+ @Override
+ public E peek() {
+ // if buffer contains no items, one cannot be retrieved
+ if(isEmpty()) {
+ throw new NoSuchElementException("Cannot retrieve item from empty Stack");
+ }
+
+ // get and return end/top item in buffer
+ return buffer[size - 1];
+ }
+
+ /**
+ * Checks to see if the stack is empty.
+ *
+ * Runtime: O(1) as we are instantly accessing a variable and checking a condition.
+ * This operation would always take the same runtime to conduct.
+ *
+ * @return true if the stack is empty, false otherwise
+ */
+ @Override
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ /**
+ * Returns a count of the number of items in the stack.
+ *
+ * Runtime: O(1) as we are instantly retrieving a variable.
+ * This operation would always take the same runtime to conduct.
+ *
+ * @return the number of items in the stack
+ */
+ @Override
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Returns an iterator over elements of type {@code T}.
+ *
+ * @return an Iterator.
+ */
+ @Override
+ public Iterator iterator() {
+ return new ReverseArrayStackIterator();
+ }
+
+ /**
+ * Implementation of an Iterator for the ReverseArrayStack class
+ */
+ private class ReverseArrayStackIterator implements Iterator
+ {
+ /**
+ * The current number of items being tracked by iterator
+ */
+ private int trackedSize;
+
+ /**
+ * Constructs an ReverseArrayStackIterator iterator, with a tracker for buffer size
+ */
+ ReverseArrayStackIterator() {
+ trackedSize = size;
+ }
+
+ /**
+ * Checks if buffer has another element, and returns true/false accordingly
+ * @return true if buffer has another element; otherwise false
+ */
+ public boolean hasNext() {
+ return trackedSize > 0;
+ }
+
+ /**
+ * Gets and returns the next/top item in the buffer
+ * @return the next/top item in the buffer
+ */
+ public E next() {
+ if(!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ // get item at end/top of buffer
+ E currItem = buffer[trackedSize];
+
+ // move down to the next item
+ trackedSize--;
+
+ return currItem;
+ }
+ }
+}
diff --git a/src/Stack.java b/src/Stack/Stack.java
similarity index 93%
rename from src/Stack.java
rename to src/Stack/Stack.java
index bb1000d..7d59c03 100644
--- a/src/Stack.java
+++ b/src/Stack/Stack.java
@@ -1,5 +1,7 @@
+package Stack;
+
/**
- * Stack (LIFO: last-in, first-out) API
+ * APIs.Stack (LIFO: last-in, first-out) API
* @param class / data type of the items in the stack
*/
public interface Stack extends Iterable {
diff --git a/src/Stack/StackTestClient.java b/src/Stack/StackTestClient.java
new file mode 100644
index 0000000..7cd74f1
--- /dev/null
+++ b/src/Stack/StackTestClient.java
@@ -0,0 +1,36 @@
+package Stack;
+
+import java.util.Scanner;
+
+public class StackTestClient {
+ public static void main(String[] args) {
+ // setup storage stack
+ //Stack storage = new ResizingArrayStack();
+ Stack storage = new LinkedStack();
+
+ // setup scanner, taking in given string
+ Scanner line = new Scanner("to be or not to - be - - that - - - is");
+
+ // run through line
+ while (line.hasNext()) {
+ // get current item
+ String item = line.next();
+
+ // if the current item is not a dash
+ if (!item.equals("-")) {
+ // it is a word, add it to stack
+ storage.push(item);
+ System.out.println();
+ }
+
+ // if it is a dash, and the stack is not empty
+ else if (!storage.isEmpty()) {
+ // pop the topmost item off the stack, and display it
+ System.out.println(storage.pop());
+ }
+ }
+
+ // display how many items remain in stack at end of line
+ System.out.println("(" + storage.size() + " left on the stack)");
+ }
+}
\ No newline at end of file
diff --git a/tests/ArrayListTest.java b/tests/ArrayListTest.java
new file mode 100644
index 0000000..c9ba03b
--- /dev/null
+++ b/tests/ArrayListTest.java
@@ -0,0 +1,731 @@
+import List.ArrayList;
+import org.junit.jupiter.api.Test;
+
+import java.util.NoSuchElementException;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+class ArrayListTest {
+ /**
+ * Create ArrayList at start for testing
+ */
+ private final ArrayList testArrayList = new ArrayList();
+
+ /**
+ * The default max capacity of buffer, at creation
+ */
+ private final int DEFAULT_BUFFER_LENGTH = 10;
+
+ /**
+ * The first index in buffer is 0
+ */
+ private final int FIRST_INDEX = 0;
+
+ /**
+ * The item returned by methods if item not found
+ */
+ private final int INVALID_INDEX = -1;
+
+ /**
+ * The standard filler item added to buffer prior to testing method
+ */
+ private final int FILLER_ITEM = 5;
+
+ /**
+ * The standard item used to test methods
+ */
+ private final int TEST_ITEM = 20;
+
+ @Test
+ void addFront_bufferContainsOneItem_addedSuccessfully() {
+ // add initial item
+ testArrayList.addBack(FILLER_ITEM);
+
+ // add expected item to front
+ testArrayList.addFront(TEST_ITEM);
+
+ // ensure expected item is at index 0
+ assertEquals(TEST_ITEM, testArrayList.get(FIRST_INDEX));
+ }
+
+ @Test
+ void addFront_bufferContainsMultipleItems_addedSuccessfully() {
+ // add several initial items
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+
+ // add expected item to front
+ testArrayList.addFront(TEST_ITEM);
+
+ // ensure expected item is at index 0
+ assertEquals(TEST_ITEM, testArrayList.get(FIRST_INDEX));
+ }
+
+ @Test
+ void addFront_bufferEmpty_addedSuccessfully() {
+ testArrayList.addFront(TEST_ITEM);
+
+ // ensure expected item is at index 0
+ assertEquals(TEST_ITEM, testArrayList.get(FIRST_INDEX));
+ }
+
+ @Test
+ void addFront_bufferFull_addedSuccessfully() {
+ // add 10 items to buffer
+ for(int i = 0; i < DEFAULT_BUFFER_LENGTH; i++) {
+ testArrayList.addBack(FILLER_ITEM);
+ }
+
+ // add 11th item to front
+ testArrayList.addFront(TEST_ITEM);
+
+ // ensure expected item is at index 0
+ assertEquals(TEST_ITEM, testArrayList.get(FIRST_INDEX));
+
+ }
+
+ @Test
+ void addBack_bufferContainsOneItem_addedSuccessfully() {
+ // add initial item
+ testArrayList.addFront(FILLER_ITEM);
+
+ // add expected item to back
+ testArrayList.addBack(TEST_ITEM);
+
+ // ensure expected item is at final index
+ assertEquals(TEST_ITEM, testArrayList.get(testArrayList.size() - 1));
+ }
+
+ @Test
+ void addBack_bufferContainsMultipleItems_addedSuccessfully() {
+ // add several initial items
+ testArrayList.addFront(FILLER_ITEM);
+ testArrayList.addFront(FILLER_ITEM);
+ testArrayList.addFront(FILLER_ITEM);
+
+ // add expected item to back
+ testArrayList.addBack(TEST_ITEM);
+
+ // ensure expected item is at final index
+ assertEquals(TEST_ITEM, testArrayList.get(testArrayList.size() - 1));
+ }
+
+ @Test
+ void addBack_bufferEmpty_addedSuccessfully() {
+ testArrayList.addBack(TEST_ITEM);
+
+ // ensure the expected item is at final index
+ assertEquals(TEST_ITEM, testArrayList.get(testArrayList.size() - 1));
+ }
+
+ @Test
+ void addBack_bufferFull_addedSuccessfully() {
+ // add 10 items to buffer
+ for(int i = 0; i < DEFAULT_BUFFER_LENGTH; i++) {
+ testArrayList.addFront(FILLER_ITEM);
+ }
+
+ // add 11th item to back
+ testArrayList.addBack(TEST_ITEM);
+
+ // ensure expected item is at final index
+ assertEquals(TEST_ITEM, testArrayList.get(testArrayList.size() - 1));
+ }
+
+ @Test
+ void add_bufferContainsOneItem_addedSuccessfully() {
+ // add initial item
+ testArrayList.addBack(FILLER_ITEM);
+
+ // add expected item to buffer
+ testArrayList.add(1, TEST_ITEM);
+
+ // ensure expected item is at final index
+ assertEquals(TEST_ITEM, testArrayList.get(testArrayList.size() - 1));
+ }
+
+ @Test
+ void add_bufferContainsMultipleItems_addedSuccessfully() {
+ // add several initial items
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+
+ // add expected item somewhere in buffer
+ testArrayList.add(2, TEST_ITEM);
+
+ // ensure expected item is at middle index
+ assertEquals(TEST_ITEM, testArrayList.get(2));
+ }
+
+ @Test
+ void add_bufferEmpty_addedSuccessfully() {
+ testArrayList.add(0, TEST_ITEM);
+
+ // ensure the expected item is at final index
+ assertEquals(TEST_ITEM, testArrayList.get(testArrayList.size() - 1));
+ }
+
+ @Test
+ void add_bufferFull_addedSuccessfully() {
+ // add 10 items to buffer
+ for(int i = 0; i < DEFAULT_BUFFER_LENGTH; i++) {
+ testArrayList.addBack(FILLER_ITEM);
+ }
+
+ // add 11th item to buffer
+ testArrayList.add(2, TEST_ITEM);
+
+ // ensure expected item is at final index
+ assertEquals(TEST_ITEM, testArrayList.get(2));
+ }
+
+ @Test
+ void add_invalidIndexNegative_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to add item at invalid index
+ testArrayList.add(-1, TEST_ITEM);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void add_invalidIndexMoreThanSize_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to add item at invalid index
+ testArrayList.add(1, TEST_ITEM);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void get_bufferContainsOneItem_returnsItem() {
+ // add expected item to buffer
+ testArrayList.addFront(TEST_ITEM);
+
+ // attempt to retrieve expected item
+ assertEquals(TEST_ITEM, testArrayList.get(FIRST_INDEX));
+ }
+
+ @Test
+ void get_bufferContainsMultipleItems_returnItem() {
+ // add several initial items
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+
+ // add item to retrieve
+ testArrayList.addBack(TEST_ITEM);
+
+ // attempt to retrieve expected item
+ assertEquals(TEST_ITEM, testArrayList.get(testArrayList.size() - 1));
+ }
+
+ @Test
+ void get_bufferEmpty_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to get item from empty buffer
+ testArrayList.get(FIRST_INDEX);
+ }
+
+ catch (NoSuchElementException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void get_invalidIndexNegative_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to get item from invalid index
+ testArrayList.get(-1);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void get_invalidIndexMoreThanSize_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to get item from invalid index
+ testArrayList.get(1);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void set_bufferContainsOneItem_setItemAtIndex() {
+ // add initial item to buffer
+ testArrayList.addFront(FILLER_ITEM);
+
+ // replace item at that index
+ testArrayList.set(FIRST_INDEX, TEST_ITEM);
+
+ // attempt to retrieve expected item
+ assertEquals(TEST_ITEM, testArrayList.get(FIRST_INDEX));
+ }
+
+ @Test
+ void set_bufferContainsMultipleItems_setItemAtIndex() {
+ // add several initial items
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+
+ // replace item at second index
+ testArrayList.set(2, TEST_ITEM);
+
+ // attempt to retrieve expected item
+ assertEquals(TEST_ITEM, testArrayList.get(2));
+ }
+
+ @Test
+ void set_bufferEmpty_setItemAtIndex() {
+ // add item to index 0 of empty buffer
+ testArrayList.set(FIRST_INDEX, TEST_ITEM);
+
+ // check if exception was thrown
+ assertEquals(TEST_ITEM, testArrayList.get(FIRST_INDEX));
+ }
+
+ @Test
+ void set_invalidIndexNegative_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to set item at invalid index
+ testArrayList.set(-1, TEST_ITEM);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void set_invalidIndexMoreThanSize_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to set item at invalid index
+ testArrayList.set(1, TEST_ITEM);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void removeFront_bufferContainsOneItem_removedSuccessfully() {
+ // add item to remove
+ testArrayList.addFront(TEST_ITEM);
+
+ // attempt to remove first item from buffer
+ assertEquals(TEST_ITEM, testArrayList.removeFront());
+
+ // ensure buffer is now empty
+ assertTrue(testArrayList.isEmpty());
+ }
+
+ @Test
+ void removeFront_bufferContainsMultipleItems_removedSuccessfully() {
+ // add several initial items
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+
+ // add item to remove
+ testArrayList.addFront(TEST_ITEM);
+
+ // attempt to remove first item from buffer
+ assertEquals(TEST_ITEM, testArrayList.removeFront());
+
+ // ensure item was removed from buffer
+ assertNotEquals(TEST_ITEM, testArrayList.get(FIRST_INDEX));
+ assertEquals(3, testArrayList.size());
+ }
+
+ @Test
+ void removeFront_bufferEmpty_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to remove item at index 0
+ testArrayList.removeFront();
+ }
+
+ catch (NoSuchElementException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void removeBack_bufferContainsOneItem_removedSuccessfully() {
+ // add item to remove
+ testArrayList.addFront(TEST_ITEM);
+
+ // attempt to remove last item from buffer
+ assertEquals(TEST_ITEM, testArrayList.removeBack());
+
+ // ensure buffer is now empty
+ assertTrue(testArrayList.isEmpty());
+ }
+
+ @Test
+ void removeBack_bufferContainsMultipleItems_removedSuccessfully() {
+ // add several initial items
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+
+ // add item to remove
+ testArrayList.addBack(TEST_ITEM);
+
+ // attempt to remove back item from buffer
+ assertEquals(TEST_ITEM, testArrayList.removeBack());
+
+ // ensure item was removed from buffer
+ assertNotEquals(TEST_ITEM, testArrayList.get(testArrayList.size()));
+ assertEquals(3, testArrayList.size());
+ }
+
+ @Test
+ void removeBack_bufferEmpty_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to remove item at index 0
+ testArrayList.removeBack();
+ }
+
+ catch (NoSuchElementException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void removeItem_bufferContainsOneItem_removedSuccessfully() {
+ // add item to remove
+ testArrayList.addBack(TEST_ITEM);
+
+ // attempt to remove item from buffer
+ testArrayList.remove((Integer) TEST_ITEM);
+
+ // ensure buffer is now empty
+ assertTrue(testArrayList.isEmpty());
+ }
+
+ @Test
+ void removeItem_bufferContainsMultipleItems_removedSuccessfully() {
+ // add several initial items
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+
+ // add item to remove
+ testArrayList.add(2, TEST_ITEM);
+
+ // attempt to remove item from buffer
+ testArrayList.remove((Integer) TEST_ITEM);
+
+ // ensure item was removed from buffer
+ assertNotEquals(TEST_ITEM, testArrayList.get(2));
+ assertEquals(3, testArrayList.size());
+ }
+
+ @Test
+ void removeItem_bufferEmpty_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to remove item from empty buffer
+ testArrayList.remove((Integer) TEST_ITEM);
+ }
+
+ catch (NoSuchElementException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void removeItem_itemNotInBuffer_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ // add several initial items
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+
+ try {
+ // attempt to remove nonexistent item from buffer
+ testArrayList.remove((Integer) TEST_ITEM);
+ }
+
+ catch (NoSuchElementException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void removeIndex_bufferContainsOneItem_removedSuccessfully() {
+ // add item to remove
+ testArrayList.addBack(TEST_ITEM);
+
+ // attempt to remove item from buffer
+ assertEquals(TEST_ITEM, testArrayList.remove(FIRST_INDEX));
+
+ // ensure buffer is now empty
+ assertTrue(testArrayList.isEmpty());
+ }
+
+ @Test
+ void removeIndex_bufferContainsMultipleItems_removedSuccessfully() {
+ // add several initial items
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+
+ // add item to remove
+ testArrayList.add(2, TEST_ITEM);
+
+ // attempt to remove item from buffer
+ assertEquals(TEST_ITEM, testArrayList.remove(2));
+
+ // ensure item was removed from buffer
+ assertEquals(3, testArrayList.size());
+ }
+
+ @Test
+ void removeIndex_bufferEmpty_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to remove item at index 0
+ testArrayList.remove(FIRST_INDEX);
+ }
+
+ catch (NoSuchElementException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void removeIndex_invalidIndexNegative_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to remove item at invalid index
+ testArrayList.remove(-1);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void removeIndex_invalidIndexMoreThanSize_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to remove item at invalid index
+ testArrayList.remove(1);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void contains_itemExists_returnsTrue() {
+ // add several initial items
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+
+ // add item to check for
+ testArrayList.addBack(TEST_ITEM);
+
+ // check if item is in buffer
+ assertTrue(testArrayList.contains(TEST_ITEM));
+ }
+
+ @Test
+ void contains_itemNotExists_returnsFalse() {
+ // add several initial items
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+
+ // check if item is in buffer
+ assertFalse(testArrayList.contains(TEST_ITEM));
+ }
+
+ @Test
+ void contains_bufferEmpty_returnsFalse() {
+ assertFalse(testArrayList.contains(TEST_ITEM));
+ }
+
+ @Test
+ void contains_bufferFullItemExists_returnsTrue() {
+ // add 9 items to buffer
+ for(int i = 0; i < DEFAULT_BUFFER_LENGTH - 1; i++) {
+ testArrayList.addBack(FILLER_ITEM);
+ }
+
+ // add test item as last item
+ testArrayList.addBack(TEST_ITEM);
+
+ // check if item is in buffer
+ assertTrue(testArrayList.contains(TEST_ITEM));
+ }
+
+ @Test
+ void isEmpty_bufferContainsOneItem_returnsFalse() {
+ // add item so the buffer is not empty
+ testArrayList.addBack(FILLER_ITEM);
+
+ assertFalse(testArrayList.isEmpty());
+ }
+
+ @Test
+ void isEmpty_bufferContainsMultipleItems_returnsFalse() {
+ // add items so the buffer is not empty
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+
+ // check if buffer is empty
+ assertFalse(testArrayList.isEmpty());
+ }
+
+ @Test
+ void isEmpty_bufferFull_returnsFalse() {
+ // add 10 items to buffer
+ for(int i = 0; i < DEFAULT_BUFFER_LENGTH; i++) {
+ testArrayList.addBack(FILLER_ITEM);
+ }
+
+ // check if buffer is empty
+ assertFalse(testArrayList.isEmpty());
+ }
+
+ @Test
+ void isEmpty_bufferEmpty_returnsTrue() {
+ // check if buffer is empty
+ assertTrue(testArrayList.isEmpty());
+ }
+
+ @Test
+ void size_bufferContainsOneItem_returnsSize() {
+ // add item so the buffer is not empty
+ testArrayList.addBack(FILLER_ITEM);
+
+ assertEquals(1, testArrayList.size());
+ }
+
+ @Test
+ void size_bufferContainsMultipleItems_returnSize() {
+ // add items so the buffer is not empty
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+ testArrayList.addBack(FILLER_ITEM);
+
+ assertEquals(3, testArrayList.size());
+ }
+
+ @Test
+ void size_bufferEmpty_returnSize() {
+ assertEquals(0, testArrayList.size());
+ }
+
+ @Test
+ void size_bufferFull_returnSize() {
+ // add 10 items to buffer
+ for(int i = 0; i < DEFAULT_BUFFER_LENGTH; i++) {
+ testArrayList.addBack(FILLER_ITEM);
+ }
+
+ assertEquals(DEFAULT_BUFFER_LENGTH, testArrayList.size());
+ }
+}
\ No newline at end of file
diff --git a/tests/LinkedListTest.java b/tests/LinkedListTest.java
new file mode 100644
index 0000000..ddde826
--- /dev/null
+++ b/tests/LinkedListTest.java
@@ -0,0 +1,652 @@
+import List.LinkedList;
+import org.junit.jupiter.api.Test;
+
+import java.util.NoSuchElementException;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class LinkedListTest {
+ /**
+ * Create LinkedList at start for testing
+ */
+ private final LinkedList testLinkedList = new LinkedList();
+
+ /**
+ * The first index in list is 0
+ */
+ private final int FIRST_INDEX = 0;
+
+ /**
+ * The standard filler item added to container prior to testing method
+ */
+ private final int FILLER_ITEM = 5;
+
+ /**
+ * The standard item used to test methods
+ */
+ private final int TEST_ITEM = 20;
+
+ /**
+ * Adds ten items to list for testing
+ */
+ private void addMultipleItems() {
+ // add 10 items to list
+ for(int i = 0; i < 10; i++) {
+ testLinkedList.addBack(FILLER_ITEM);
+ }
+ }
+
+ @Test
+ void addFront_hasItem_addedSuccessfully() {
+ // add initial item
+ testLinkedList.addBack(FILLER_ITEM);
+
+ // add test item
+ testLinkedList.addFront(TEST_ITEM);
+
+ // ensure expected item is at index 0
+ assertEquals(TEST_ITEM, testLinkedList.get(FIRST_INDEX));
+ }
+
+ @Test
+ void addFront_hasMultipleItems_addedSuccessfully() {
+ // add several initial items
+ addMultipleItems();
+
+ // add test item
+ testLinkedList.addFront(TEST_ITEM);
+
+ // ensure expected item is at index 0
+ assertEquals(TEST_ITEM, testLinkedList.get(FIRST_INDEX));
+ }
+
+ @Test
+ void addFront_empty_addedSuccessfully() {
+ // make test item new head
+ testLinkedList.addFront(TEST_ITEM);
+
+ // ensure expected item is at index 0
+ assertEquals(TEST_ITEM, testLinkedList.get(FIRST_INDEX));
+ }
+
+ @Test
+ void addBack_hasItem_addedSuccessfully() {
+ // add initial item
+ testLinkedList.addFront(FILLER_ITEM);
+
+ // add test item
+ testLinkedList.addBack(TEST_ITEM);
+
+ // ensure expected item is at end of list
+ assertEquals(TEST_ITEM, testLinkedList.get(testLinkedList.size() -1));
+ }
+
+ @Test
+ void addBack_hasMultipleItems_addedSuccessfully() {
+ // add several initial items
+ addMultipleItems();
+
+ // add test item
+ testLinkedList.addBack(TEST_ITEM);
+
+ // ensure expected item is at end of list
+ assertEquals(TEST_ITEM, testLinkedList.get(testLinkedList.size() -1));
+ }
+
+ @Test
+ void addBack_empty_addedSuccessfully() {
+ // make test item new tail
+ testLinkedList.addBack(TEST_ITEM);
+
+ // ensure expected item is at end of list
+ assertEquals(TEST_ITEM, testLinkedList.get(testLinkedList.size() -1));
+ }
+
+ @Test
+ void add_hasItem_addedSuccessfully() {
+ // add initial item
+ testLinkedList.addFront(FILLER_ITEM);
+
+ // add test item
+ testLinkedList.add(testLinkedList.size(), TEST_ITEM);
+
+ // ensure expected item is at expected index
+ assertEquals(TEST_ITEM, testLinkedList.get(testLinkedList.size() - 1));
+ }
+
+ @Test
+ void add_hasMultipleItems_addedSuccessfully() {
+ // add several initial items
+ addMultipleItems();
+
+ // add test item
+ testLinkedList.add(4, TEST_ITEM);
+
+ // ensure expected item is at expected index
+ assertEquals(TEST_ITEM, testLinkedList.get(4));
+ }
+
+ @Test
+ void add_empty_addedSuccessfully() {
+ // add test item to list
+ testLinkedList.add(FIRST_INDEX, TEST_ITEM);
+
+ // ensure expected item is in list
+ assertEquals(TEST_ITEM, testLinkedList.get(FIRST_INDEX));
+ }
+
+ @Test
+ void add_invalidIndexNegative_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to add item at invalid index
+ testLinkedList.add(FIRST_INDEX - 1, TEST_ITEM);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void add_invalidIndexMoreThanSize_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to add item at invalid index
+ testLinkedList.add(FIRST_INDEX + 1, TEST_ITEM);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void get_hasItem_returnsItem() {
+ // add expected item to list
+ testLinkedList.addFront(TEST_ITEM);
+
+ // attempt to retrieve expected item
+ assertEquals(TEST_ITEM, testLinkedList.get(FIRST_INDEX));
+ }
+
+ @Test
+ void get_hasMultipleItems_returnsItem() {
+ // add several initial items
+ addMultipleItems();
+
+ // add item to retrieve
+ testLinkedList.addBack(TEST_ITEM);
+
+ // attempt to retrieve expected item at final index
+ assertEquals(TEST_ITEM, testLinkedList.get(testLinkedList.size() - 1));
+ }
+
+ @Test
+ void get_listEmpty_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to get item from empty list
+ testLinkedList.get(FIRST_INDEX);
+ }
+
+ catch (NoSuchElementException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void get_invalidIndexNegative_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to get item from invalid index
+ testLinkedList.get(FIRST_INDEX - 1);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void get_invalidIndexMoreThanSize_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to get item from invalid index
+ testLinkedList.get(FIRST_INDEX + 1);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void set_hasItem_setItemAtIndex() {
+ // add initial item to list
+ testLinkedList.addFront(FILLER_ITEM);
+
+ // replace item at that index
+ testLinkedList.set(FIRST_INDEX, TEST_ITEM);
+
+ // attempt to retrieve expected item
+ assertEquals(TEST_ITEM, testLinkedList.get(FIRST_INDEX));
+ }
+
+ @Test
+ void set_hasMultipleItems_setItemAtIndex() {
+ // add several initial items
+ addMultipleItems();
+
+ // replace item at sixth index
+ testLinkedList.set(6, TEST_ITEM);
+
+ // attempt to retrieve expected item
+ assertEquals(TEST_ITEM, testLinkedList.get(6));
+ }
+
+ @Test
+ void set_empty_setItemAtIndex() {
+ // add item to index 0 of empty list
+ testLinkedList.set(FIRST_INDEX, TEST_ITEM);
+
+ // attempt to retrieve expected item
+ assertEquals(TEST_ITEM, testLinkedList.get(FIRST_INDEX));
+
+ // ensure size tracker was updated
+ assertEquals(1, testLinkedList.size());
+ }
+
+ @Test
+ void set_invalidIndexNegative_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to set item at invalid index
+ testLinkedList.set(FIRST_INDEX - 1, TEST_ITEM);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void set_invalidIndexMoreThanSize_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to set item at invalid index
+ testLinkedList.set(FIRST_INDEX + 1, TEST_ITEM);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void removeFront_hasItem_removedSuccessfully() {
+ // add item to remove
+ testLinkedList.addFront(TEST_ITEM);
+
+ // attempt to remove item from list
+ assertEquals(TEST_ITEM, testLinkedList.removeFront());
+
+ // ensure list is now empty
+ assertTrue(testLinkedList.isEmpty());
+ }
+
+ @Test
+ void removeFront_hasMultipleItems_removedSuccessfully() {
+ // add several initial items
+ addMultipleItems();
+
+ // add item to remove
+ testLinkedList.addFront(TEST_ITEM);
+
+ // attempt to remove front item from list
+ testLinkedList.removeFront();
+
+ // ensure item was removed from list
+ assertNotEquals(TEST_ITEM, testLinkedList.get(FIRST_INDEX));
+ assertFalse(testLinkedList.contains(TEST_ITEM));
+ assertEquals(10, testLinkedList.size());
+ }
+
+ @Test
+ void removeFront_empty_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to remove nonexistent item
+ testLinkedList.removeFront();
+ }
+
+ catch (NoSuchElementException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void removeBack_hasItem_removedSuccessfully() {
+ // add item to remove
+ testLinkedList.addBack(TEST_ITEM);
+
+ // attempt to remove item from list
+ testLinkedList.removeFront();
+
+ // ensure list is now empty
+ assertTrue(testLinkedList.isEmpty());
+ }
+
+ @Test
+ void removeBack_hasMultipleItems_removedSuccessfully() {
+ // add several initial items
+ addMultipleItems();
+
+ // add item to remove
+ testLinkedList.addBack(TEST_ITEM);
+
+ // attempt to remove front item from list
+ testLinkedList.removeBack();
+
+ // ensure item was removed from list
+ assertNotEquals(TEST_ITEM, testLinkedList.get(testLinkedList.size() - 1));
+ assertFalse(testLinkedList.contains(TEST_ITEM));
+ assertEquals(10, testLinkedList.size());
+ }
+
+ @Test
+ void removeBack_empty_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to remove nonexistent item
+ testLinkedList.removeBack();
+ }
+
+ catch (NoSuchElementException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ //
+
+ @Test
+ void removeItem_hasItem_removedSuccessfully() {
+ // add item to remove
+ testLinkedList.addBack(TEST_ITEM);
+
+ // attempt to remove item from list
+ testLinkedList.remove((Integer) TEST_ITEM);
+
+ // ensure list is now empty
+ assertTrue(testLinkedList.isEmpty());
+ }
+
+ @Test
+ void removeItem_hasMultipleItems_removedSuccessfully() {
+ // add several initial items
+ addMultipleItems();
+
+ // add item to remove
+ testLinkedList.add(9, TEST_ITEM);
+
+ // attempt to remove item from list
+ testLinkedList.remove((Integer) TEST_ITEM);
+
+ // ensure item was removed from list
+ assertNotEquals(TEST_ITEM, testLinkedList.get(9));
+ assertFalse(testLinkedList.contains(TEST_ITEM));
+ assertEquals(10, testLinkedList.size());
+ }
+
+ @Test
+ void removeItem_empty_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to remove item from empty list
+ testLinkedList.remove((Integer) TEST_ITEM);
+ }
+
+ catch (NoSuchElementException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void removeItem_itemNotExists_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ // add several initial items
+ addMultipleItems();
+
+ try {
+ // attempt to remove nonexistent item from list
+ testLinkedList.remove((Integer) TEST_ITEM);
+ }
+
+ catch (NoSuchElementException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void removeIndex_hasItem_removedSuccessfully() {
+ // add item to remove
+ testLinkedList.addBack(TEST_ITEM);
+
+ // attempt to remove item from list
+ assertEquals(TEST_ITEM, testLinkedList.remove(FIRST_INDEX));
+
+ // ensure list is now empty
+ assertTrue(testLinkedList.isEmpty());
+ }
+
+ @Test
+ void removeIndex_removeItemFromMiddle_removedSuccessfully() {
+ // add several initial items
+ addMultipleItems();
+
+ // add item to remove
+ testLinkedList.add(7, TEST_ITEM);
+
+ // attempt to remove item from list
+ assertEquals(TEST_ITEM, testLinkedList.remove(7));
+
+ // ensure item was removed from list
+ assertFalse(testLinkedList.contains(TEST_ITEM));
+ assertEquals(10, testLinkedList.size());
+ }
+
+ @Test
+ void removeIndex_removeItemFromEnd_removedSuccessfully() {
+ // add several initial items
+ addMultipleItems();
+
+ // add item to remove
+ testLinkedList.add(testLinkedList.size(), TEST_ITEM);
+
+ // attempt to remove item from list
+ assertEquals(TEST_ITEM, testLinkedList.remove(testLinkedList.size()));
+
+ // ensure item was removed from list
+ assertFalse(testLinkedList.contains(TEST_ITEM));
+ assertEquals(10, testLinkedList.size());
+ }
+
+ @Test
+ void removeIndex_empty_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to remove nonexistent item
+ testLinkedList.remove(FIRST_INDEX);
+ }
+
+ catch (NoSuchElementException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void removeIndex_invalidIndexNegative_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to remove item at invalid index
+ testLinkedList.remove(FIRST_INDEX - 1);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void removeIndex_invalidIndexMoreThanSize_throwsException() {
+ // setup flag
+ boolean exceptionThrown = false;
+
+ try {
+ // attempt to remove item at invalid index
+ testLinkedList.remove(FIRST_INDEX + 1);
+ }
+
+ catch (IndexOutOfBoundsException e) {
+ exceptionThrown = true;
+ }
+
+ // check if exception was thrown
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ void contains_itemExists_returnsTrue() {
+ // add several initial items
+ addMultipleItems();
+
+ // add item to check for
+ testLinkedList.addBack(TEST_ITEM);
+
+ // check if item is in list
+ assertTrue(testLinkedList.contains(TEST_ITEM));
+ }
+
+ @Test
+ void contains_itemNotExists_returnsFalse() {
+ // add several initial items
+ addMultipleItems();
+
+ // check if item is in list
+ assertFalse(testLinkedList.contains(TEST_ITEM));
+ }
+
+ @Test
+ void contains_empty_returnsFalse() {
+ assertFalse(testLinkedList.contains(TEST_ITEM));
+ }
+
+ @Test
+ void isEmpty_hasItem_returnsFalse() {
+ // add item so the list is not empty
+ testLinkedList.addFront(FILLER_ITEM);
+
+ assertFalse(testLinkedList.isEmpty());
+ }
+
+ @Test
+ void isEmpty_hasMultipleItems_returnsFalse() {
+ // add items so list is not empty
+ addMultipleItems();
+
+ // check if list is empty
+ assertFalse(testLinkedList.isEmpty());
+ }
+
+ @Test
+ void isEmpty_empty_returnsTrue() {
+ // check if list is empty
+ assertTrue(testLinkedList.isEmpty());
+ }
+
+ @Test
+ void size_hasItem_returnsSize() {
+ // add item so list is not empty
+ testLinkedList.addFront(FILLER_ITEM);
+
+ assertEquals(1, testLinkedList.size());
+ }
+
+ @Test
+ void size_hasMultipleItems_returnsSize() {
+ // add items so the list is not empty
+ addMultipleItems();
+
+ assertEquals(10, testLinkedList.size());
+ }
+
+ @Test
+ void size_empty_returnsSize() {
+ assertEquals(0, testLinkedList.size());
+ }
+}
\ No newline at end of file