From 36121bdd04bdd351cf6073a9e2d669c2c14bd74b Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Tue, 9 Jan 2024 13:17:34 -0800 Subject: [PATCH 01/16] Added starter code, finished some of the easy methods. --- src/ArrayIntList.java | 183 ++++++++++++++++++++++++++++++++++++++++++ src/Main.java | 10 +-- 2 files changed, 188 insertions(+), 5 deletions(-) create mode 100644 src/ArrayIntList.java diff --git a/src/ArrayIntList.java b/src/ArrayIntList.java new file mode 100644 index 0000000..d74afd1 --- /dev/null +++ b/src/ArrayIntList.java @@ -0,0 +1,183 @@ +import java.util.Iterator; + +public class ArrayIntList implements IntList +{ + + //fields + private int size; + private int[] buffer; + + public ArrayIntList () + { + size = 0; + buffer = new int[10]; + } + + /** + * Prepends (inserts) the specified value at the front of the list (at index 0). + * Shifts the value currently at the front of the list (if any) and any + * subsequent values to the right. + * + * @param value value to be inserted + */ + @java.lang.Override + public void addFront(int value) + { + //index shuffle + for (int i = size - 1; i > -1; i--) + { + buffer[i + 1] = buffer[i]; + } + + //put the value at position 0 + buffer[0] = value; + size++; + } + + /** + * Appends (inserts) the specified value at the back of the list (at index size()-1). + * + * @param value value to be inserted + */ + @java.lang.Override + public void addBack(int value) + { + //TODO: check to see if we are full - if so, we need to create a larger buffer + + buffer[size] = value; + size++; + } + + /** + * Inserts the specified value at the specified position in this list. + * Shifts the value currently at that position (if any) and any subsequent + * values to the right. + * + * @param index index at which the specified value is to be inserted + * @param value value to be inserted + * @throws IndexOutOfBoundsException if the index is out of range + */ + @java.lang.Override + public void add(int index, int value) + { + + } + + /** + * Removes the value located at the front of the list + * (at index 0), if it is present. + * Shifts any subsequent values to the left. + */ + @java.lang.Override + public void removeFront() + { + + } + + /** + * Removes the value located at the back of the list + * (at index size()-1), if it is present. + */ + @java.lang.Override + public void removeBack() + { + + } + + /** + * Removes the value at the specified position in this list. + * Shifts any subsequent values to the left. Returns the value + * that was removed from the list. + * + * @param index the index of the value to be removed + * @return the value previously at the specified position + * @throws IndexOutOfBoundsException if the index is out of range + */ + @java.lang.Override + public int remove(int index) + { + return 0; + } + + /** + * Returns the value at the specified position in the list. + * + * @param index index of the value to return + * @return the value at the specified position in this list + * @throws IndexOutOfBoundsException if the index is out of range + */ + @java.lang.Override + public int get(int index) + { + return 0; + } + + /** + * Returns true if this list contains the specified value. + * + * @param value value whose presence in this list is to be searched for + * @return true if this list contains the specified value + */ + @java.lang.Override + public boolean contains(int value) + { + return false; + } + + /** + * Returns the index of the first occurrence of the specified value + * in this list, or -1 if this list does not contain the value. + * + * @param value value to search for + * @return the index of the first occurrence of the specified value in this list + * or -1 if this list does not contain the value + */ + @java.lang.Override + public int indexOf(int value) + { + return 0; + } + + /** + * Returns true if this list contains no values. + * + * @return true if this list contains no values + */ + @java.lang.Override + public boolean isEmpty() + { + return false; + } + + /** + * Returns the number of values in this list. + * + * @return the number of values in this list + */ + @java.lang.Override + public int size() + { + return 0; + } + + /** + * Removes all the values from this list. + * The list will be empty after this call returns. + */ + @java.lang.Override + public void clear() + { + + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() + { + return null; + } +} diff --git a/src/Main.java b/src/Main.java index 930198c..5a89559 100644 --- a/src/Main.java +++ b/src/Main.java @@ -6,10 +6,10 @@ public static void main(String[] args) { // to see how IntelliJ IDEA suggests fixing it. System.out.printf("Hello and welcome!"); - for (int i = 1; i <= 5; i++) { - //TIP Press to start debugging your code. We have set one breakpoint - // for you, but you can always add more by pressing . - System.out.println("i = " + i); - } + IntList firstList; + + ArrayIntList secondList = new ArrayIntList(); + + IntList thirdList = new ArrayIntList(); } } \ No newline at end of file From 74d0be3928736dd0717a0b7c42949e3e7813aaf1 Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Tue, 9 Jan 2024 13:46:30 -0800 Subject: [PATCH 02/16] Completed the remove method. --- src/ArrayIntList.java | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/ArrayIntList.java b/src/ArrayIntList.java index d74afd1..7ff3e44 100644 --- a/src/ArrayIntList.java +++ b/src/ArrayIntList.java @@ -96,7 +96,29 @@ public void removeBack() @java.lang.Override public int remove(int index) { - return 0; + if (index < 0) + { + throw new IndexOutOfBoundsException("Index cannot be negative."); + } + else if (index >= size) + { + throw new IndexOutOfBoundsException("Invalid index"); + } + + //save a copy of the value to be removed so we can return it later + int returnValue = buffer[index]; + + //shift values from upper indexes down + for (int i = index; i < size; i++) + { + buffer[i] = buffer[i + 1]; + } + buffer[size - 1] = 0; + + //decrement the size of the list + size--; + + return returnValue; } /** From 9439b112634d6ebb68eb3c75d758366a51ab5058 Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Tue, 9 Jan 2024 13:47:28 -0800 Subject: [PATCH 03/16] Completed the remove method. --- src/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Main.java b/src/Main.java index 5a89559..8ac55cb 100644 --- a/src/Main.java +++ b/src/Main.java @@ -4,7 +4,7 @@ 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.printf("Hello and welcome!"); + System.out.print("Hello and welcome!"); IntList firstList; From 4068b6597a3fedac3681006edf34cbcc851d60fa Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Tue, 9 Jan 2024 13:49:04 -0800 Subject: [PATCH 04/16] Altered a print statement to remove redundancy. --- src/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Main.java b/src/Main.java index 8ac55cb..92ddddc 100644 --- a/src/Main.java +++ b/src/Main.java @@ -4,7 +4,7 @@ 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.print("Hello and welcome!"); + System.out.println("Hello and welcome!"); IntList firstList; From 7fbcaeea423d6652d6d9e16b700f430e8d486d38 Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Tue, 9 Jan 2024 13:54:24 -0800 Subject: [PATCH 05/16] Completed the clear method. --- src/ArrayIntList.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ArrayIntList.java b/src/ArrayIntList.java index 7ff3e44..280b070 100644 --- a/src/ArrayIntList.java +++ b/src/ArrayIntList.java @@ -189,7 +189,14 @@ public int size() @java.lang.Override public void clear() { + buffer = new int[10]; + size = 0; +// clean, efficient method. Too slow. +// while (size != 0) +// { +// remove(0); +// } } /** From fa574cdcd301ae664ef8776795857774d46084ff Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Tue, 9 Jan 2024 14:15:24 -0800 Subject: [PATCH 06/16] Added an internally-used "resize" method. --- src/ArrayIntList.java | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/ArrayIntList.java b/src/ArrayIntList.java index 280b070..91f4d37 100644 --- a/src/ArrayIntList.java +++ b/src/ArrayIntList.java @@ -60,7 +60,10 @@ public void addBack(int value) @java.lang.Override public void add(int index, int value) { - +// if (size == buffer.length) +// { +// resize(size * 2); +// } } /** @@ -199,6 +202,24 @@ public void clear() // } } + private void resize(int newSize) + { + //create a new space, separate from the old one + int[] newBuffer = new int[newSize]; + + //copy everything over from buffer into newBuffer + for (int i = 0; i < size; i++) + { + newBuffer[i] = buffer[i]; + } + + //set the new space into buffer + buffer = newBuffer; + + //the old buffer space is no longer "pointed to" and will eventually be cleaned up by the + //garbage collector + } + /** * Returns an iterator over elements of type {@code T}. * From 5789c0a187351ccf246ba1903cc42d1908997a7e Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Tue, 9 Jan 2024 14:33:31 -0800 Subject: [PATCH 07/16] Added an internal iterator class to ArrayIntList and a foreach loop to Main. --- src/ArrayIntList.java | 54 +++++++++++++++++++++++++++++++++++++++---- src/Main.java | 24 +++++++++++++++++++ 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/ArrayIntList.java b/src/ArrayIntList.java index 91f4d37..fc4cd92 100644 --- a/src/ArrayIntList.java +++ b/src/ArrayIntList.java @@ -1,4 +1,5 @@ import java.util.Iterator; +import java.util.NoSuchElementException; public class ArrayIntList implements IntList { @@ -60,10 +61,10 @@ public void addBack(int value) @java.lang.Override public void add(int index, int value) { -// if (size == buffer.length) -// { -// resize(size * 2); -// } + if (size == buffer.length) + { + resize(size * 2); + } } /** @@ -228,6 +229,51 @@ private void resize(int newSize) @Override public Iterator iterator() { + return null; } + + //create a private helper Iterator class + private class IntListIterator implements Iterator + { + //private fields + private int i; + + private IntListIterator() + { + i = 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 i < 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 Integer next() + { + if (i >= size) + { + throw new NoSuchElementException("i is out of bounds"); + } + + int currentValue = buffer[i]; + i++; + return currentValue; + } + } } diff --git a/src/Main.java b/src/Main.java index 92ddddc..09dde83 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,3 +1,5 @@ +import java.util.Iterator; + //TIP To Run code, press or // click the icon in the gutter. public class Main { @@ -11,5 +13,27 @@ public static void main(String[] args) { ArrayIntList secondList = new ArrayIntList(); IntList thirdList = new ArrayIntList(); + thirdList.addFront(15); + thirdList.addFront(12); + thirdList.addBack(8); + + //where an iterator gets used: + for (int value : thirdList) + { + System.out.println(value); + } + +// alternate way to use an iterator +// Iterator itr = thirdList.iterator(); +// while(itr.hasNext()) +// { +// int value = itr.next(); +// System.out.println(value); +// } + } + + public static double findAverage(IntList theList) + { + } } \ No newline at end of file From 68d0c6c7892ab042bdae9062e9394e9f831c4904 Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Tue, 16 Jan 2024 14:35:48 -0800 Subject: [PATCH 08/16] Created a class that represents a doubly-linked list. Implemented the removeBack() and addBack() methods. --- src/DoublyLinkedIntList.java | 238 +++++++++++++++++++++++++++++++++++ src/LinkedIntList.java | 198 +++++++++++++++++++++++++++++ src/Main.java | 2 +- 3 files changed, 437 insertions(+), 1 deletion(-) create mode 100644 src/DoublyLinkedIntList.java create mode 100644 src/LinkedIntList.java diff --git a/src/DoublyLinkedIntList.java b/src/DoublyLinkedIntList.java new file mode 100644 index 0000000..19fef8b --- /dev/null +++ b/src/DoublyLinkedIntList.java @@ -0,0 +1,238 @@ +import java.util.Iterator; + +public class DoublyLinkedIntList implements IntList +{ + //private fields + private class Node + { + int data; + Node next; //address of the Node "after" this one + Node prev; //address of the Node "before" this one + + public Node() + { + //by default, Nodes will point to null. + next = null; + prev = null; + } + } + + private Node pre; + private Node post; + private int size; + + //These two Nodes are sentinel Nodes; dummy Nodes that serve as bookends to the doubly-linked list. + //They aren't necessary, but they make the job much easier. + + //constructor + public DoublyLinkedIntList() + { + //an empty list has 2 sentinel Nodes; they sandwich all the important stuff that gets added later. + pre = new Node(); + post = new Node(); + + //making the two sentinels point to each other + pre.next = post; + post.prev = pre; + + size = 0; + } + + /** + * Prepends (inserts) the specified value at the front of the list (at index 0). + * Shifts the value currently at the front of the list (if any) and any + * subsequent values to the right. + * + * @param value value to be inserted + */ + @Override + public void addFront(int value) + { + + } + + /** + * Appends (inserts) the specified value at the back of the list (at index size()-1). + * + * @param value value to be inserted + */ + @Override + public void addBack(int value) + { + //storing the old "last" Node + Node theLastOne = post.prev; + + //construct a new Node at the back of the list + Node theNewOne = new Node(); + theNewOne.data = value; + theNewOne.next = post; + theNewOne.prev = theLastOne; + + //re-route the sentinels + post.prev = theNewOne; + pre.next = theNewOne; + + //re-route the old "last" Node to point to our newly-created last Node + theLastOne.next = theNewOne; + + //increment the size of the list + size++; + } + + /** + * Inserts the specified value at the specified position in this list. + * Shifts the value currently at that position (if any) and any subsequent + * values to the right. + * + * @param index index at which the specified value is to be inserted + * @param value value to be inserted + * @throws IndexOutOfBoundsException if the index is out of range + */ + @Override + public void add(int index, int value) + { + + } + + /** + * Removes the value located at the front of the list + * (at index 0), if it is present. + * Shifts any subsequent values to the left. + */ + @Override + public void removeFront() + { + + } + + /** + * Removes the value located at the back of the list + * (at index size()-1), if it is present. + */ + @Override + public void removeBack() + { + //if the list isn't empty... + if (size > 0) + { + //starting from the back bookend, pointing to the "last" Node in the list + Node theOneToRemove = post.prev; + + //accessing the Node before the "last" one and re-routing it to the back bookend + theOneToRemove.prev.next = post; + + //stealing the "prev" pointer from the "last" Node and using it to re-route the back bookend to the new "last" + post.prev = theOneToRemove.prev; + + //completely clearing the old "last" Node; it's redundant, but for peace of mind. + //the Garbage Collector will sweep the Node up regardless of whether you clear the Node's values or not. + theOneToRemove.next = null; + theOneToRemove.prev = null; + theOneToRemove.data = 0; + + //de-increment the size of the list + size--; + } + else + { + throw new IllegalStateException("List is empty. Nothing can be removed."); + } + } + + /** + * Removes the value at the specified position in this list. + * Shifts any subsequent values to the left. Returns the value + * that was removed from the list. + * + * @param index the index of the value to be removed + * @return the value previously at the specified position + * @throws IndexOutOfBoundsException if the index is out of range + */ + @Override + public int remove(int index) + { + return 0; + } + + /** + * Returns the value at the specified position in the list. + * + * @param index index of the value to return + * @return the value at the specified position in this list + * @throws IndexOutOfBoundsException if the index is out of range + */ + @Override + public int get(int index) + { + return 0; + } + + /** + * Returns true if this list contains the specified value. + * + * @param value value whose presence in this list is to be searched for + * @return true if this list contains the specified value + */ + @Override + public boolean contains(int value) + { + return false; + } + + /** + * Returns the index of the first occurrence of the specified value + * in this list, or -1 if this list does not contain the value. + * + * @param value value to search for + * @return the index of the first occurrence of the specified value in this list + * or -1 if this list does not contain the value + */ + @Override + public int indexOf(int value) + { + return 0; + } + + /** + * Returns true if this list contains no values. + * + * @return true if this list contains no values + */ + @Override + public boolean isEmpty() + { + return false; + } + + /** + * Returns the number of values in this list. + * + * @return the number of values in this list + */ + @Override + public int size() + { + return 0; + } + + /** + * Removes all the values from this list. + * The list will be empty after this call returns. + */ + @Override + public void clear() + { + + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() + { + return null; + } +} diff --git a/src/LinkedIntList.java b/src/LinkedIntList.java new file mode 100644 index 0000000..58fffbd --- /dev/null +++ b/src/LinkedIntList.java @@ -0,0 +1,198 @@ +import java.util.Iterator; + +public class LinkedIntList implements IntList +{ + + //define what a node is + private class Node + { + int data; + Node next; + + + } + + //set up the head of the list + private Node head; + + //set up the size field + private int size; + + //constructor + public LinkedIntList() + { + head = null; + size = 0; + } + + /** + * Prepends (inserts) the specified value at the front of the list (at index 0). + * Shifts the value currently at the front of the list (if any) and any + * subsequent values to the right. + * + * @param value value to be inserted + */ + @Override + public void addFront(int value) + { + //set up a new node + Node theNewOne = new Node(); + + if (head == null) + { + //the list is currently empty + head = theNewOne; + size++; + } + else + { + //the list currently has nodes in it + theNewOne.next = head; + head = theNewOne; + } + } + + /** + * Appends (inserts) the specified value at the back of the list (at index size()-1). + * + * @param value value to be inserted + */ + @Override + public void addBack(int value) + { + + } + + /** + * Inserts the specified value at the specified position in this list. + * Shifts the value currently at that position (if any) and any subsequent + * values to the right. + * + * @param index index at which the specified value is to be inserted + * @param value value to be inserted + * @throws IndexOutOfBoundsException if the index is out of range + */ + @Override + public void add(int index, int value) + { + + } + + /** + * Removes the value located at the front of the list + * (at index 0), if it is present. + * Shifts any subsequent values to the left. + */ + @Override + public void removeFront() + { + + } + + /** + * Removes the value located at the back of the list + * (at index size()-1), if it is present. + */ + @Override + public void removeBack() + { + + } + + /** + * Removes the value at the specified position in this list. + * Shifts any subsequent values to the left. Returns the value + * that was removed from the list. + * + * @param index the index of the value to be removed + * @return the value previously at the specified position + * @throws IndexOutOfBoundsException if the index is out of range + */ + @Override + public int remove(int index) + { + return 0; + } + + /** + * Returns the value at the specified position in the list. + * + * @param index index of the value to return + * @return the value at the specified position in this list + * @throws IndexOutOfBoundsException if the index is out of range + */ + @Override + public int get(int index) + { + return 0; + } + + /** + * Returns true if this list contains the specified value. + * + * @param value value whose presence in this list is to be searched for + * @return true if this list contains the specified value + */ + @Override + public boolean contains(int value) + { + return false; + } + + /** + * Returns the index of the first occurrence of the specified value + * in this list, or -1 if this list does not contain the value. + * + * @param value value to search for + * @return the index of the first occurrence of the specified value in this list + * or -1 if this list does not contain the value + */ + @Override + public int indexOf(int value) + { + return 0; + } + + /** + * Returns true if this list contains no values. + * + * @return true if this list contains no values + */ + @Override + public boolean isEmpty() + { + return false; + } + + /** + * Returns the number of values in this list. + * + * @return the number of values in this list + */ + @Override + public int size() + { + return 0; + } + + /** + * Removes all the values from this list. + * The list will be empty after this call returns. + */ + @Override + public void clear() + { + + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() + { + return null; + } +} diff --git a/src/Main.java b/src/Main.java index 09dde83..d9d76c5 100644 --- a/src/Main.java +++ b/src/Main.java @@ -34,6 +34,6 @@ public static void main(String[] args) { public static double findAverage(IntList theList) { - + return 0.0; } } \ No newline at end of file From 6c7d78ab071b96521ba8ca56c806c193d4b6f075 Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Tue, 23 Jan 2024 13:54:10 -0800 Subject: [PATCH 09/16] Implemented the public-facing iterator() methods for both ArrayIntList.java and LinkedIntList.java. Also implemented the removeFront() and removeBack() methods for ArrayIntList.java. --- src/ArrayIntList.java | 27 +++++++++++++++++++--- src/LinkedIntList.java | 52 +++++++++++++++++++++++++++++++++++++++--- src/Main.java | 18 +++++++-------- 3 files changed, 82 insertions(+), 15 deletions(-) diff --git a/src/ArrayIntList.java b/src/ArrayIntList.java index fc4cd92..1e748dc 100644 --- a/src/ArrayIntList.java +++ b/src/ArrayIntList.java @@ -74,8 +74,21 @@ public void add(int index, int value) */ @java.lang.Override public void removeFront() - { + { if (!isEmpty()) + { + for (int i = 0; i <= size - 2; i++) + { + buffer[i] = buffer[i + 1]; + } + //clearing out the rightmost index + buffer[size - 1] = 0; + size--; + } + else + { + System.out.println("List is empty. Nothing to remove."); + } } /** @@ -85,7 +98,15 @@ public void removeFront() @java.lang.Override public void removeBack() { - + if (!isEmpty()) + { + buffer[size - 1] = 0; + size--; + } + else + { + System.out.println("List is empty. Nothing to remove."); + } } /** @@ -230,7 +251,7 @@ private void resize(int newSize) public Iterator iterator() { - return null; + return new IntListIterator(); } //create a private helper Iterator class diff --git a/src/LinkedIntList.java b/src/LinkedIntList.java index 58fffbd..93742b5 100644 --- a/src/LinkedIntList.java +++ b/src/LinkedIntList.java @@ -1,4 +1,5 @@ import java.util.Iterator; +import java.util.NoSuchElementException; public class LinkedIntList implements IntList { @@ -8,8 +9,6 @@ private class Node { int data; Node next; - - } //set up the head of the list @@ -193,6 +192,53 @@ public void clear() @Override public Iterator iterator() { - return null; + return new SinglyLinkedIterator(); + } + + //helper class/type that defines how the iterator works + private class SinglyLinkedIterator implements Iterator + { + + private Node current; + + public SinglyLinkedIterator() + { + 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() + { + //compute the result of whether or not current equals null, then return it + 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 Integer next() + { + if (current != null) + { + int item = current.data; + current = current.next; + return item; + } + else + { + throw new NoSuchElementException("End of list reached."); + } + } } } diff --git a/src/Main.java b/src/Main.java index d9d76c5..c2c0047 100644 --- a/src/Main.java +++ b/src/Main.java @@ -18,18 +18,18 @@ public static void main(String[] args) { thirdList.addBack(8); //where an iterator gets used: - for (int value : thirdList) - { - System.out.println(value); - } - -// alternate way to use an iterator -// Iterator itr = thirdList.iterator(); -// while(itr.hasNext()) +// for (int value : thirdList) // { -// int value = itr.next(); // System.out.println(value); // } + +// alternate way to use an iterator + Iterator itr = thirdList.iterator(); + while(itr.hasNext()) + { + int value = itr.next(); + System.out.println(value); + } } public static double findAverage(IntList theList) From 159069495874eb4412ffd0e5e136c61886c025b0 Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Tue, 23 Jan 2024 14:04:25 -0800 Subject: [PATCH 10/16] Updated addBack() in ArrayIntList.java with a check to see if the buffer is full. --- src/ArrayIntList.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ArrayIntList.java b/src/ArrayIntList.java index 1e748dc..56cdeb1 100644 --- a/src/ArrayIntList.java +++ b/src/ArrayIntList.java @@ -45,6 +45,12 @@ public void addBack(int value) { //TODO: check to see if we are full - if so, we need to create a larger buffer + //if the buffer is full, double the size. + if (size == buffer.length) + { + resize(size * 2); + } + buffer[size] = value; size++; } From 7a3c407f80749e43fad27cadba38db1d3bddf168 Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Sat, 27 Jan 2024 15:04:50 -0800 Subject: [PATCH 11/16] Filled in the remaining few methods for ArrayIntList.java: get(), contains(), indexOf(), isEmpty(), and size(). --- src/ArrayIntList.java | 50 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/src/ArrayIntList.java b/src/ArrayIntList.java index 56cdeb1..028b15f 100644 --- a/src/ArrayIntList.java +++ b/src/ArrayIntList.java @@ -162,7 +162,20 @@ else if (index >= size) @java.lang.Override public int get(int index) { - return 0; + //checking to make sure the user doesn't enter a number that's out of bounds + if (index > size) + { + throw new IndexOutOfBoundsException("Provided index is too large."); + } + else if (index < 0) //same here + { + throw new IndexOutOfBoundsException("Indexes cannot be negative."); + } + else + { + //if the index is within the bounds of the ArrayIntList, give the user the data at the provided index. + return buffer[index]; + } } /** @@ -174,6 +187,16 @@ public int get(int index) @java.lang.Override public boolean contains(int value) { + //run through the entire ArrayIntList to check for the provided value + for (int i = 0; i < size; i++) + { + if (buffer[i] == value) + { + //if the value is found, stop right there and return true + return true; + } + } + //if the loop reaches its end, that means the value wasn't found; return false. return false; } @@ -188,7 +211,17 @@ public boolean contains(int value) @java.lang.Override public int indexOf(int value) { - return 0; + //there's probably some way to recycle contains for this, but I'm not smart enough to do it right now. + for (int i = 0; i < size; i++) + { + //if the provided value is found in the ArrayIntList, return the index (i) that it was found at. + if (buffer[i] == value) + { + return i; + } + } + //if the loop reaches its end, then chances are the value isn't in the ArrayIntList, so return -1. + return -1; } /** @@ -199,7 +232,15 @@ public int indexOf(int value) @java.lang.Override public boolean isEmpty() { - return false; + //if the size is 0, then the ArrayIntList should be empty, right? + if (size == 0) + { + return true; + } + else + { + return false; + } } /** @@ -210,7 +251,8 @@ public boolean isEmpty() @java.lang.Override public int size() { - return 0; + //just return the size variable. + return size; } /** From 832bdd90eef290891ec67e8f6e0fd4b57aea7a6b Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Sat, 27 Jan 2024 15:44:52 -0800 Subject: [PATCH 12/16] Wrote up some tests for ArrayIntList.java. Some of them are currently not functioning the way they should. Also attempted to re-implement the add() method, as for some reason it appears that it was never properly put in. --- .idea/test/ArrayIntTest.java | 98 ++++++++++++++++++++++++++++++++++++ src/ArrayIntList.java | 24 ++++++++- 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 .idea/test/ArrayIntTest.java diff --git a/.idea/test/ArrayIntTest.java b/.idea/test/ArrayIntTest.java new file mode 100644 index 0000000..5946a35 --- /dev/null +++ b/.idea/test/ArrayIntTest.java @@ -0,0 +1,98 @@ +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.Random; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ArrayIntTest +{ + private static ArrayIntList testList; + + @BeforeAll + static void createList() + { + testList = new ArrayIntList(); + Random numGen = new Random(); + + testList.addFront(5); + for (int i = 0; i < 4; i++) + { + testList.addFront(numGen.nextInt(0,100)); + } + } + + @Test + void addFront() + { + System.out.println("Expected value: 79"); + testList.addFront(79); + System.out.println("Actual value: " + testList.get(0)); + } + + @Test + void addBack() + { + System.out.println("Expected value: 31"); + testList.addBack(31); + System.out.println("Actual value: " + testList.get(testList.size() - 1)); + } + + @Test + void add() + { + System.out.println("Expected value at index 8: 2"); + testList.add(8, 2); + System.out.println("Actual value at index 8: " + testList.get(8)); + } + + @Test + void removeFront() + { + System.out.println("Expected value at list front: " + testList.get(1)); + testList.removeFront(); + System.out.println("Actual value at list front: " + testList.get(0)); + } + + @Test + void removeBack() + { + System.out.println("Expected value at list end: " + testList.get(testList.size() - 2)); + testList.removeBack(); + System.out.println("Actual value at list end: " + testList.get(testList.size() - 1)); + } + + @Test + void remove() + { + System.out.println("Expected value at index 3: " + testList.get(4)); + testList.remove(3); + System.out.println("Actual value at index 3: " + testList.get(3)); + } + + @Test + void contains() + { + assertEquals(true, testList.contains(5)); + } + + @Test + void indexOf() + { + assertEquals(0, testList.indexOf(5)); + } + + @Test + void isEmpty() + { + assertEquals(false, testList.isEmpty()); + } + + @Test + void clear() + { + testList.clear(); + assertEquals(true, testList.isEmpty()); + } +} diff --git a/src/ArrayIntList.java b/src/ArrayIntList.java index 028b15f..3c39b81 100644 --- a/src/ArrayIntList.java +++ b/src/ArrayIntList.java @@ -1,3 +1,11 @@ +/** + * This file contains a data structure designed to mimic an ArrayList; however, it only accepts integers instead of + * any data type. + * + * @author Jared Eller + * @version 1.0 + */ + import java.util.Iterator; import java.util.NoSuchElementException; @@ -71,6 +79,19 @@ public void add(int index, int value) { resize(size * 2); } + + //shuffling stuff over if the current index isn't empty + if (buffer[index] != 0) + { + for (int i = size - 1; i > -1; i--) + { + buffer[i + 1] = buffer[i]; + } + } + + //inserting the value at the index + buffer[index] = value; + size++; } /** @@ -80,7 +101,8 @@ public void add(int index, int value) */ @java.lang.Override public void removeFront() - { if (!isEmpty()) + { + if (!isEmpty()) { for (int i = 0; i <= size - 2; i++) { From e5b796e569c917458ec8ef2b004178871f913901 Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Sat, 27 Jan 2024 16:55:38 -0800 Subject: [PATCH 13/16] Attempted to implement as many methods into LinkedIntList.java as I could; these include addBack(), add(), removeFront(), removeBack(), remove(), get(), contains(), indexOf(), isEmpty(), size(), and clear(). Code is completely untested, no time to write test cases for any of these. --- src/LinkedIntList.java | 222 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 216 insertions(+), 6 deletions(-) diff --git a/src/LinkedIntList.java b/src/LinkedIntList.java index 93742b5..c6cbea1 100644 --- a/src/LinkedIntList.java +++ b/src/LinkedIntList.java @@ -48,6 +48,7 @@ public void addFront(int value) //the list currently has nodes in it theNewOne.next = head; head = theNewOne; + size++; } } @@ -59,7 +60,24 @@ public void addFront(int value) @Override public void addBack(int value) { + //set up a new node + Node theNewOne = new Node(); + //getting an iterator set up + SinglyLinkedIterator iterator = new SinglyLinkedIterator(); + + //as long as there's another node, scoot the iterator forward along the list. + while(iterator.hasNext()) + { + iterator.current = iterator.current.next; + } + + //if the iterator can't move forward, then put the new Node into that empty space. + if(!iterator.hasNext()) + { + iterator.current.next = theNewOne; + size++; + } } /** @@ -74,7 +92,31 @@ public void addBack(int value) @Override public void add(int index, int value) { + //setting up a size variable and an iterator to walk through the list + int currentIndex = 0; + SinglyLinkedIterator iterator = new SinglyLinkedIterator(); + //as long as the next index isn't the one where the new value belongs AND the next index exists, move forward. + while (currentIndex != index + 1 && iterator.hasNext()) + { + iterator.current = iterator.current.next; + currentIndex++; + } + //if the next index IS the one where the value belongs, then create a new node there and link it to the old + //"next". + if (currentIndex + 1 == index) + { + //to start, create a new Node. link it up to the current "next" node. + Node theNewOne = new Node(); + theNewOne.next = iterator.current.next; + + //now, link up the current Node to the newly-created "next" node. + iterator.current.next = theNewOne; + + //I hope it's that simple... + //wait, increment the size. + size++; + } } /** @@ -85,7 +127,26 @@ public void add(int index, int value) @Override public void removeFront() { + //Re-wire "head" to point to the Node in front of the node to be removed, then... let the GC grab it? + //I think... + if (head == null) + { + System.out.println("Empty list! Sorry!"); + } + else + { + //storing the front node in a proper variable + Node theOneToRemove = head.next; + + //adjusting head's pointer to point to the next one in the list + head.next = theOneToRemove.next; + + //cutting off the old front from the rest of the list entirely + theOneToRemove.next = null; + //decrement the size... + size--; + } } /** @@ -95,7 +156,24 @@ public void removeFront() @Override public void removeBack() { + //so, check if the Node in front of the current one's "next" field is null? And if it is, that must be the + //back of the list. In which case, cut off the current one's "next" field so that the old "back" floats off + //and gets eaten by the GC. + SinglyLinkedIterator iterator = new SinglyLinkedIterator(); + + //as long as the Node in front of this one doesn't have a null pointer... + while(iterator.current.next.next != null) + { + //go forward. + iterator.current = iterator.current.next; + } + //if we're at the second-to-last node... + if (iterator.current.next.next == null) + { + //let the last node go. It's IDE food now. + iterator.current.next = null; + } } /** @@ -110,7 +188,50 @@ public void removeBack() @Override public int remove(int index) { - return 0; + if (index > size) + { + throw new IndexOutOfBoundsException("Provided index is too high."); + } + else if (index < 0) + { + throw new IndexOutOfBoundsException("Negative indexes are not supported."); + } + else + { + //walk through the list, keeping track of what node you're on, and when your pointer is pointing to the Node + //you're looking for, store that Node in a variable, grab its pointer to redirect your current Node, then + //set the stored Node's next to null so it floats away like a piece of driftwood in the ocean. + + //gonna recycle some of my solution for add(), really hoping this works since it's largely untested... + + //setting up a size variable and an iterator to walk through the list + int currentIndex = 0; + SinglyLinkedIterator iterator = new SinglyLinkedIterator(); + + //as long as the next index isn't the index indicated AND the next index exists, move forward. + while (currentIndex != index + 1 && iterator.hasNext()) + { + iterator.current = iterator.current.next; + currentIndex++; + } + //if the next index IS the one we're looking for, store that Node in a variable. + if (currentIndex + 1 == index) + { + //store the Node in a variable. + Node theOneToRemove = iterator.current.next; + + //from here, I need to grab the pointer from this new variable and give it to the current Node. + iterator.current.next = theOneToRemove.next; + + //cut the stored Node's next field and return its data. + //also decrement the list size. + size--; + theOneToRemove.next = null; + return theOneToRemove.data; + } + } + //otherwise, return -1, I suppose. + return -1; } /** @@ -123,7 +244,39 @@ public int remove(int index) @Override public int get(int index) { - return 0; + if (index > size) + { + throw new IndexOutOfBoundsException("Provided index is too high."); + } + else if (index < 0) + { + throw new IndexOutOfBoundsException("Negative indexes are not supported."); + } + else + { + //walk through the list, keeping track of what node you're on, and when your pointer is pointing to the Node + //you're looking for, return the Node data at that particular index. + + //gonna recycle some of my solution for add(), really hoping this works since it's largely untested... + + //setting up a size variable and an iterator to walk through the list + int currentIndex = 0; + SinglyLinkedIterator iterator = new SinglyLinkedIterator(); + + //as long as the next index isn't the index indicated AND the next index exists, move forward. + while (currentIndex != index + 1 && iterator.hasNext()) + { + iterator.current = iterator.current.next; + currentIndex++; + } + //if the next index IS the one we're looking for, return the data at that index. + if (currentIndex + 1 == index) + { + return iterator.current.next.data; + } + } + //otherwise, return -1. + return -1; } /** @@ -135,6 +288,23 @@ public int get(int index) @Override public boolean contains(int value) { + //walk through the list, keeping track of what node you're on, and if the Node you're on has the value you're + //looking for, return true. Otherwise, return false. + + //gonna recycle some of my solution for add(), really hoping this works since it's largely untested... + + SinglyLinkedIterator iterator = new SinglyLinkedIterator(); + + //as long as the next index exists, check for the value and move forward. + while (iterator.hasNext()) + { + if (iterator.current.data == value) + { + return true; + } + iterator.current = iterator.current.next; + } + //if the iterator makes it to the end of the list and didn't return true, then it's not here. return false. return false; } @@ -149,7 +319,36 @@ public boolean contains(int value) @Override public int indexOf(int value) { - return 0; + + //walk through the list, keeping track of what node you're on, and if your current Node has the data being + //requested in it, return the currentIndex variable. Otherwise, keep going. + + //gonna recycle some of my solution for add(), really hoping this works since it's largely untested... + + //setting up a size variable and an iterator to walk through the list + int currentIndex = 0; + SinglyLinkedIterator iterator = new SinglyLinkedIterator(); + + //as long as the next index exists, move forward. + while (iterator.hasNext()) + { + //check for if the value's here... + if (iterator.current.data == value) + { + //if it is, return the current index. + return currentIndex; + } + else + { + //if it isn't, iterate the current index instead. + currentIndex++; + } + //then move forward. + iterator.current = iterator.current.next; + + } + //if it isn't found by the time the iterator reaches the end of the list it's not here. return -1. + return -1; } /** @@ -160,7 +359,15 @@ public int indexOf(int value) @Override public boolean isEmpty() { - return false; + //just check if the size is 0; if it is, it's empty. If it isn't, it's not empty. + if (size == 0) + { + return true; + } + else + { + return false; + } } /** @@ -171,7 +378,8 @@ public boolean isEmpty() @Override public int size() { - return 0; + //just return the size field. + return size; } /** @@ -181,7 +389,9 @@ public int size() @Override public void clear() { - + //make a new one entirely. Wipe the slate clean. + head = null; + size = 0; } /** From c527d765c1d1628b3424a784dd45d7a93552a455 Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Sat, 27 Jan 2024 16:58:24 -0800 Subject: [PATCH 14/16] Added documentation to LinkedIntList.java. --- src/LinkedIntList.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/LinkedIntList.java b/src/LinkedIntList.java index c6cbea1..55c6fe4 100644 --- a/src/LinkedIntList.java +++ b/src/LinkedIntList.java @@ -1,3 +1,9 @@ +/** + * This class attempts to imitate a LinkedList, with the exception that it only allows integers in its data field. + * + * @author Jared Eller + */ + import java.util.Iterator; import java.util.NoSuchElementException; From 1e6dc791e4ef59ebf1b04c388ced2131ec55d83e Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Mon, 29 Jan 2024 12:43:57 -0800 Subject: [PATCH 15/16] Implemented the addFront(), add(), removeFront(), remove(), get(), contains(), indexOf(), isEmpty(), size(), clear() and iterator() methods; also touched up addBack() to be more robust. --- src/DoublyLinkedIntList.java | 333 ++++++++++++++++++++++++++++++++--- 1 file changed, 312 insertions(+), 21 deletions(-) diff --git a/src/DoublyLinkedIntList.java b/src/DoublyLinkedIntList.java index 19fef8b..7f6b0b0 100644 --- a/src/DoublyLinkedIntList.java +++ b/src/DoublyLinkedIntList.java @@ -1,4 +1,5 @@ import java.util.Iterator; +import java.util.NoSuchElementException; public class DoublyLinkedIntList implements IntList { @@ -48,7 +49,41 @@ public DoublyLinkedIntList() @Override public void addFront(int value) { + //set up a new node + Node theNewOne = new Node(); + theNewOne.data = value; + //looking back, it occurs to me that I completely forgot to make the nodes in my LinkedIntList submission + //actually store the user's inputted data for the add methods... whoops. + + //check if the list is empty or not + if (pre.next == null) + { + //if it is, put it in and point the sentinels to it. + theNewOne.prev = pre; + theNewOne.next = post; + + pre.next = theNewOne; + post.prev = theNewOne; + + //then increment the size. + size++; + } + else + { + //if the list isn't empty, store the current "front" in a variable, then "rewire" the "front" and first + //sentinel to have the proper pointers to the "new" front. + Node oldFront = pre.next; + + theNewOne.prev = pre; + theNewOne.next = oldFront; + + pre.next = theNewOne; + oldFront.prev = theNewOne; + + //increment the size + size++; + } } /** @@ -59,24 +94,32 @@ public void addFront(int value) @Override public void addBack(int value) { - //storing the old "last" Node - Node theLastOne = post.prev; - - //construct a new Node at the back of the list + //set up a new node Node theNewOne = new Node(); theNewOne.data = value; - theNewOne.next = post; - theNewOne.prev = theLastOne; - //re-route the sentinels - post.prev = theNewOne; - pre.next = theNewOne; + //check if the list is empty or not + if (pre.next == null) + { + //if it is, just recycle addFront(). There are no nodes besides the sentinels, so order doesn't matter much. + addFront(value); + } + else + { + //if the list isn't empty, store the current "back" in a local variable. Wire up theNewOne, then re-wire + //the affected nodes so they point to theNewOne. + + Node oldBack = post.prev; - //re-route the old "last" Node to point to our newly-created last Node - theLastOne.next = theNewOne; + theNewOne.prev = oldBack; + theNewOne.next = post; - //increment the size of the list - size++; + post.prev = theNewOne; + oldBack.next = theNewOne; + + //increment the size + size++; + } } /** @@ -91,7 +134,54 @@ public void addBack(int value) @Override public void add(int index, int value) { - + if (index > size) + { + throw new IndexOutOfBoundsException("Provided index is too large."); + } + else if (index < 0) + { + throw new IndexOutOfBoundsException("Provided index cannot be negative."); + } + else + { + //gonna need an iterator, a node to hold the value, and an index counter variable. + LinkedIterator iterator = new LinkedIterator(); + Node newNode = new Node(); + newNode.data = value; + int currentIndex = 0; + + //check if the list is empty; if it is, just recycle addFront(). If it isn't, get to walkin' + if (pre.next == null) + { + addFront(value); + } + else + { + //scan ahead one Node to ensure that current doesn't accidentally go too far + while(currentIndex + 1 != index) + { + iterator.current = iterator.current.next; + currentIndex++; + } + + if(currentIndex + 1 == index) + { + //scoot the current node at the user-provided index outta the way; first off, store it in a variable + Node oldNode = iterator.current.next; + + //now wire up the new node so it points to both the "current" node and the "old" node + newNode.prev = iterator.current; + newNode.next = oldNode; + + //re-wire the Nodes as necessary + iterator.current.next = newNode; + oldNode.prev = newNode; + + //iterate the count + size++; + } + } + } } /** @@ -102,7 +192,45 @@ public void add(int index, int value) @Override public void removeFront() { + //if the size isn't 0 or 1, since 1 wouldn't work with this solution + if (size > 1) + { + //Grab the first Node in the list and store it in a variable + Node theOneToRemove = pre.next; + + //now, re-wire the Nodes. + pre.next = theOneToRemove.next; + theOneToRemove.next.prev = pre; + + //wipe the slate clean just to be sure. + theOneToRemove.prev = null; + theOneToRemove.next = null; + theOneToRemove.data = 0; + + //de-increment the list + size--; + } + else if (size == 1) + { + //now for something a little different: store the Node, reset pre/post's pointers back to null. + //Then wipe the Node. + Node theOneToRemove = pre.next; + + pre.next = null; + post.prev = null; + + theOneToRemove.prev = null; + theOneToRemove.next = null; + theOneToRemove.data = 0; + //and decrement the size... + size--; + } + else + { + //in case the list is empty, throw an exception. Kind of worried I'm getting too trigger-happy with these... + throw new NoSuchElementException("The list is empty. Nothing to remove."); + } } /** @@ -151,7 +279,40 @@ public void removeBack() @Override public int remove(int index) { - return 0; + //gonna need an iterator and an index variable for this one. + LinkedIterator iterator = new LinkedIterator(); + int currentIndex = 0; + + int dataToReturn = -1; + + //walk through the list. Might've been able to make this into a method... + while (currentIndex + 1 != index) + { + iterator.current = iterator.current.next; + currentIndex++; + } + + //if the index is coming up, then go ahead and pop the data out of that Node. + if (currentIndex + 1 == index) + { + Node nodeToRemove = iterator.current.next; + dataToReturn = nodeToRemove.data; + + //from there, wire the Nodes to go around this Node. + iterator.current.next = nodeToRemove.next; + nodeToRemove.next.prev = iterator.current; + + //blank out the nodeToRemove entirely. + nodeToRemove.prev = null; + nodeToRemove.next = null; + nodeToRemove.data = 0; + + //decrement the size. + size--; + } + + //return the data. + return dataToReturn; } /** @@ -164,7 +325,34 @@ public int remove(int index) @Override public int get(int index) { - return 0; + //iterator and index variable needed. + LinkedIterator iterator = new LinkedIterator(); + int currentIndex = 0; + int dataToReturn = -1; + + if (index > size) + { + throw new IndexOutOfBoundsException("The provided index is too large."); + } + else if (index < 0) + { + throw new IndexOutOfBoundsException("Negative indexes are not permitted."); + } + else + { + while (currentIndex + 1 != index) + { + iterator.current = iterator.current.next; + currentIndex++; + } + + if (currentIndex + 1 == index) + { + dataToReturn = iterator.current.next.data; + return dataToReturn; + } + } + return dataToReturn; } /** @@ -176,6 +364,25 @@ public int get(int index) @Override public boolean contains(int value) { + //iterator for this one. + LinkedIterator iterator = new LinkedIterator(); + + //as long as the next field isn't null, meaning we're not at post... + while(iterator.current.next != null) + { + //check to see if the current Node's value is what we're looking for. + if (iterator.current.data == value) + { + //if it is, return true and break out of this method. + return true; + } + else + { + //otherwise, keep marchin' forward. + iterator.current = iterator.current.next; + } + } + //if the loop reaches its end, then logically, the provided value isn't in here. Return false. return false; } @@ -190,7 +397,32 @@ public boolean contains(int value) @Override public int indexOf(int value) { - return 0; + //iterator and index variable for this one. + LinkedIterator iterator = new LinkedIterator(); + int currentIndex = 0; + + //am I wrong in thinking some of this code could be turned into its own method? How far should I go when it + //comes to making my code atomic in size? Maybe Josh imprinted on me too much... + + //we're gonna roll on the assumption that the value is present in the list. + while (iterator.current.next != null) + { + //roll through the list until "next" is null, which would mean we've reached post, which doesn't have data + //in it in the first place. + if (iterator.current.data == value) + { + //if we've got the data, then go ahead and return the current index. + return currentIndex; + } + else + { + //if we don't have the data yet, take a step over to the next Node and increase the current index. + iterator.current = iterator.current.next; + currentIndex++; + } + } + //if we never find it, then return -1. + return -1; } /** @@ -201,7 +433,14 @@ public int indexOf(int value) @Override public boolean isEmpty() { - return false; + if (size == 0) + { + return true; + } + else + { + return false; + } } /** @@ -212,7 +451,8 @@ public boolean isEmpty() @Override public int size() { - return 0; + //self-explanatory since we keep track of the size in a variable. + return size; } /** @@ -222,7 +462,10 @@ public int size() @Override public void clear() { - + //wipe the slate clean. + pre.next = null; + post.prev = null; + size = 0; } /** @@ -233,6 +476,54 @@ public void clear() @Override public Iterator iterator() { - return null; + return new LinkedIterator(); + } + + //helper class/type that defines how the iterator works + //much of this was copy/pasted over from LinkedIntList.java. + private class LinkedIterator implements Iterator + { + + private DoublyLinkedIntList.Node current; + + public LinkedIterator() + { + current = pre; + } + + /** + * 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() + { + //compute the result of whether or not current equals null, then return it + 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 Integer next() + { + if (current != null) + { + int item = current.data; + current = current.next; + return item; + } + else + { + throw new NoSuchElementException("End of list reached."); + } + } } } From 49298f112725408a8183cfdf17721cf6d4c0dde9 Mon Sep 17 00:00:00 2001 From: jEllerGRC Date: Mon, 29 Jan 2024 13:22:55 -0800 Subject: [PATCH 16/16] Added a bit of documentation to DoublyLinkedIntList.java, up at the top of the file. Also created a series of tests for DoublyLinkedIntList.java, contained in the file DoublyLinkedTests.java. That being said, these tests themselves are completely untested; the test file would not run in my IDE and I'm unsure why. --- .idea/test/DoublyLinkedTests.java | 212 ++++++++++++++++++++++++++++++ src/DoublyLinkedIntList.java | 6 + 2 files changed, 218 insertions(+) create mode 100644 .idea/test/DoublyLinkedTests.java diff --git a/.idea/test/DoublyLinkedTests.java b/.idea/test/DoublyLinkedTests.java new file mode 100644 index 0000000..48a4ae7 --- /dev/null +++ b/.idea/test/DoublyLinkedTests.java @@ -0,0 +1,212 @@ +/** + * This class contains tests for DoublyLinkedIntList.java. + * + * @author Jared Eller + */ + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DoublyLinkedTests +{ + private static DoublyLinkedIntList emptyTestList; + private static DoublyLinkedIntList oneTestList; + private static DoublyLinkedIntList twoTestList; +// private static DoublyLinkedIntList fullTestList; +// by nature I don't think LinkedLists can really be full, aside from running out of memory... + @BeforeAll + static void createList() + { + emptyTestList = new DoublyLinkedIntList(); + oneTestList = new DoublyLinkedIntList(); + twoTestList = new DoublyLinkedIntList(); + + oneTestList.addFront(72); + twoTestList.addFront(14); + twoTestList.addFront(108); + } + + @Test + static void addFront() + { + //showing how adding a value to the list changes the starting value, thus showing the method works the way it + //should. + System.out.println(emptyTestList.get(1)); + emptyTestList.addFront(5); + System.out.println(emptyTestList.get(1)); + + System.out.println(oneTestList.get(1)); + oneTestList.addFront(5); + System.out.println(oneTestList.get(1)); + + System.out.println(twoTestList.get(1)); + twoTestList.addFront(5); + System.out.println(twoTestList.get(1)); + + //testing with incorrect data input; this is commented out since it'll break the compilation if it runs. +// emptyTestList.addFront("orange"); + } + + @Test + static void addBack() + { + //showing how adding a value to the list changes the back value, thus showing the method works the way it + //should. + //I suppose this also technically serves as a test for size, but I'll try to write a proper test for that + //if I get the chance. + System.out.println(emptyTestList.get(emptyTestList.size())); + emptyTestList.addBack(25); + System.out.println(emptyTestList.get(emptyTestList.size())); + + System.out.println(oneTestList.get(oneTestList.size())); + oneTestList.addFront(25); + System.out.println(oneTestList.get(oneTestList.size())); + + System.out.println(twoTestList.get(twoTestList.size())); + twoTestList.addFront(25); + System.out.println(twoTestList.get(twoTestList.size())); + } + + @Test + static void add() + { + //this one's gonna test a few different indices cuz of how the lists are set up. + System.out.println(emptyTestList.get(1)); + emptyTestList.add(125, 1); + System.out.println(emptyTestList.get(1)); + System.out.println(emptyTestList.get(2)); + + System.out.println(oneTestList.get(3)); + oneTestList.add(125, 3); + System.out.println(oneTestList.get(3)); + System.out.println(oneTestList.get(4)); + + System.out.println(twoTestList.get(4)); + twoTestList.add(125, 4); + System.out.println(twoTestList.get(4)); + System.out.println(twoTestList.get(5)); + //Doing two "sout"s per list to show the data moving to accomodate the newly-added Nodes. + } + + @Test + static void removeFront() + { + //I think the way I wrote get means 1 is actually index 0, hence me constantly getting index 1 instead of 0. + System.out.println(emptyTestList.get(1)); + emptyTestList.removeFront(); + System.out.println(emptyTestList.get(1)); + + System.out.println(oneTestList.get(1)); + oneTestList.removeFront(); + System.out.println(oneTestList.get(1)); + + System.out.println(twoTestList.get(1)); + twoTestList.removeFront(); + System.out.println(twoTestList.get(1)); + + //the logic I'm using with these tests is the same logic I used earlier on: print out the data in the index + //to be altered, then do the alteration, then print out the new data. Not a lot of assertEquals here... + } + + @Test + static void removeBack() + { + System.out.println(emptyTestList.get(emptyTestList.size())); + emptyTestList.removeBack(); + System.out.println(emptyTestList.get(emptyTestList.size())); + + System.out.println(oneTestList.get(emptyTestList.size())); + oneTestList.removeBack(); + System.out.println(oneTestList.get(emptyTestList.size())); + + System.out.println(twoTestList.get(emptyTestList.size())); + twoTestList.removeBack(); + System.out.println(twoTestList.get(emptyTestList.size())); + } + + @Test + static void remove() + { + //praying that these tests just work, I gotta go to work in about 20 minutes... + System.out.println(emptyTestList.get(2)); + emptyTestList.remove(2); + + //actually, this may throw an exception. +// System.out.println(emptyTestList.get(2)); + assertEquals((Integer) null, emptyTestList.get(2)); //I hope this works... + + System.out.println(oneTestList.get(2)); + oneTestList.remove(2); + System.out.println(oneTestList.get(2)); + + System.out.println(twoTestList.get(3)); + twoTestList.remove(3); + System.out.println(twoTestList.get(3)); + + //I feel like a lot of these tests were written awkwardly; instead of finding a way to effectively use + //assertEquals, I just put the work on the end-user by printing the values out and asking them to compare. + //Very sloppy work. + } + + @Test + static void get() + { + //now, the real question: null, or -1? + assertEquals(-1, emptyTestList.get(1)); + assertEquals(72, oneTestList.get(1)); + assertEquals(108, twoTestList.get(1)); + } + + @Test + static void contains() + { + assertEquals(1, emptyTestList.contains(1)); //should be false + assertEquals(72, oneTestList.contains(72)); //should be true + assertEquals(14, twoTestList.contains(14)); //should be true + } + + @Test + static void indexOf() + { + //can't test emptyTestList cuz I assumed the value being searched for would be present upon a call of indexOf. + assertEquals(1, oneTestList.indexOf(72)); //should be 1 + assertEquals(2, twoTestList.indexOf(14)); //should be 2 + } + + @Test + static void isEmpty() + { + //empty should be empty, one should have 1, two should have 2. + assertEquals(true, emptyTestList.isEmpty()); + assertEquals(false, oneTestList.isEmpty()); + assertEquals(false, twoTestList.isEmpty()); + } + + @Test + static void size() + { + assertEquals(0, emptyTestList.size()); + assertEquals(1, oneTestList.size()); + assertEquals(2, twoTestList.size()); + } + + @Test + static void clear() + { + //this might cause some exceptions cuz of emptyTestList being... well... empty. + System.out.println(emptyTestList.get(1)); + System.out.println(oneTestList.get(1)); + System.out.println(twoTestList.get(1)); + + emptyTestList.clear(); + oneTestList.clear(); + twoTestList.clear(); + + //these will probably throw exceptions, or else return -1, a designated dummy value... + System.out.println(emptyTestList.get(1)); + System.out.println(oneTestList.get(1)); + System.out.println(twoTestList.get(1)); + } +} diff --git a/src/DoublyLinkedIntList.java b/src/DoublyLinkedIntList.java index 7f6b0b0..816fa48 100644 --- a/src/DoublyLinkedIntList.java +++ b/src/DoublyLinkedIntList.java @@ -1,3 +1,9 @@ +/** + * This class represents a doubly-linked list. + * + * @author Jared Eller + */ + import java.util.Iterator; import java.util.NoSuchElementException;