From f853c0cc752cf9c4105ce8da1c04afb8a254a561 Mon Sep 17 00:00:00 2001 From: AdamZWinter Date: Wed, 11 Jan 2023 13:24:17 -0800 Subject: [PATCH 01/11] From CS145 --- src/CardArrayList.java | 246 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 src/CardArrayList.java diff --git a/src/CardArrayList.java b/src/CardArrayList.java new file mode 100644 index 0000000..950ee37 --- /dev/null +++ b/src/CardArrayList.java @@ -0,0 +1,246 @@ +import java.util.*; + +/**The CardArrayList object contains an array of Cards and povides methods for manipulating that array + * While the actual array may contain null values at indexes greater than the size of the Collection of Cards it contains, + * the public methods provided here give access to only the properties of the portion of the array that holds that Collection + * + * @author Adam Winter + * @version + */ +public class CardArrayList implements CardList +{ + + private Card[] ca; //card array + private int size; + + /** Constructor: a new CardArrayList with size 0 (zero) but an internal array with length 10 + * + */ + public CardArrayList(){ + this.ca = new Card[10]; + this.size = 0; + } + + /**Constructor: a new CardArrayList with size 0 (zero) but an internal array with length equal to the argument + * + * @param x The size to intialize the internal array + * @throws IllegalArgumentException The size of the array must be at least zero. + * + */ + public CardArrayList(int x) throws IllegalArgumentException{ + if(x < 0)throw new IllegalArgumentException("The size of the array must be at least zero."); + this.ca = new Card[x]; + this.size = 0; + } + + + /** This returns a representation of the list from index 0 to the final index. + * + * @return The string visulation of the list. + */ + public String toString(){ + String strCards = "[0: "; + for(int i = 0; i < this.size; i++){ + if(i == 0){ + strCards = strCards + ca[i].toString(); + }else{ + strCards = strCards + "," + ca[i].toString(); + } + }//end for + strCards = strCards + " :" + this.size + "]"; + return strCards; + }//end toString() + + /** This method returns the current number of elements in the list. + * Note, this is not the length of the interal array, but the number of Cards in the collection + * + * @return the size of the list as an integer + */ + public int size(){ + return this.size; + } + + + /** This method adds a card to the end of the list in the first available spot. + * The size of the internal array is checked first, and expanded if there is not room + * + * @param c the Card object to be added. + */ + public void add(Card c){ + if(!this.isRoom()){ + this.expand(); + this.ca[this.size] = c; + this.size++; + }else{ + this.ca[this.size] = c; + this.size++; + } + } + + + /** This adds a card to the indicated location, per the given argument, sliding all other elements over one. + * + * @param loc the desired index of the card to be added. + * @param c the Card object to be added. + * @throws IndexOutOfBoundsException if the loc is outside the current list. + */ + public void add(int loc, Card c) throws IndexOutOfBoundsException { + if(loc < 0 || loc > this.size) throw new IndexOutOfBoundsException("Index out of bounds in call to add(int, Card)"); + if(!this.isRoom()){ + this.expand(); + for(int i = this.size; i >= loc + 1; i--){ + this.ca[i] = this.ca[i - 1]; + } + this.ca[loc] = c; + this.size++; + }else{ + for(int i = this.size; i >= loc + 1; i--){ + this.ca[i] = this.ca[i - 1]; + } + this.ca[loc] = c; + this.size++; + } + }//end add + + + /** This method removes the last element from the list, and returns it. + * + * @return The card object removed from the list. + * @throws IndexOutOfBoundsException if the list is empty. + */ + public Card remove() throws IndexOutOfBoundsException { + if(this.size == 0)throw new IndexOutOfBoundsException("The list is empty, but you called remove()."); + this.size--; + return this.ca[this.size]; + } + + /** This removes the identified card from the list and return it. + * The remain cards to the right then slide the the left + * + * @param loc the index of the card to be removed. + * @return The card object removed from the list. + * @throws IndexOutOfBoundsException if the loc is outside the current array size. + */ + public Card remove(int loc) throws IndexOutOfBoundsException { + if(loc < 0 || loc >= this.size) throw new IndexOutOfBoundsException("Index out of bounds in call to remove(int)."); + Card requested = this.ca[loc]; + for (int i = loc; i < this.size - 1; i++){ + this.ca[i] = this.ca[i + 1]; + } + this.size--; + return requested; + } + + /** This returns the element from the list that is the index provided as the argument + * + * @param i The index of the desired card. + * @return The card object locatated in index x from the list. + * @throws IndexOutOfBoundsException if the i value is outside the range of the list + */ + public Card get(int i) throws IndexOutOfBoundsException{ + if(i < 0 || i >= this.size) throw new IndexOutOfBoundsException("Index is out of bounds in call to get()."); + return this.ca[i]; + }//end get + + /** Returns the index of specified Card object + * + * @param c Card object + * @return index of Card otherwise -1 if not found + */ + public int indexOf(Card c){ + for (int i = 0; i < size; i++){ + if(this.ca[i].equals(c)){ + return i; + } + } + return -1; + } + + /** Sort the items in the list from smallest to largest + * + */ + public void sort(){ + if(this.size < 2)return; + Card[] exact = new Card[this.size]; //learned this lesson the long and hard way + for(int i = 0; i < this.size; i++){ // Before the list can be sorted, the null positions in the array are removed + exact[i] = this.ca[i]; // This is done by copying all the Cards into an array of the exact size needed + } + this.ca = exact; //The main/internal array that hold the collection is then set to the new array + mergeSort(this.ca); //And then it is sorted + } + + //standard mergeSort using recursion + private void mergeSort(Card[] ca){ + if(ca.length > 1){ + Card[] left = Arrays.copyOfRange(ca, 0, ca.length/2); + Card[] right = Arrays.copyOfRange(ca, ca.length/2, ca.length); + mergeSort(left); + mergeSort(right); + merge(ca, left, right); + }//end if + }//end mergeSort + + //standard merge for a mergeSort + private void merge(Card[] result, Card[] left, Card[] right){ + int i1 = 0; + int i2 = 0; + for(int i = 0; i < result.length; i++){ //started by taking this directly from the book + if(i2 >= right.length) { + result[i] = left[i1]; + i1++; + }else if(i1 >= left.length) { //split this into pieces while troubleshooting the problem I was having before I realized + result[i] = right[i2]; //that the array needed to be trimmed of the null values to the exact size + i2++; //otherwise you end up trying to sort null values + }else if(left[i1].compareTo(right[i2]) < 0){ //this is the line where the null valus first become a problem + result[i] = left[i1]; + i1++; + }else{ + result[i] = right[i2]; + i2++; + } + }//end for + }//end merge + + /** Not such a weak shuffle algorithm; Shuffles the collection of Cards + * + */ + public void shuffle(){ + CardList shuffledList = new CardArrayList(this.size); //create a new CardArrayList + Random rand = new Random(); + for(int i = this.size - 1; i >= 0; i--){ + shuffledList.add(this.remove(rand.nextInt(i + 1))); //randomly remove cards from the original List and add them to the new one + } + for(int i = 0; i < shuffledList.size(); i++){ //put all the cards back into the original List in the new shuffled order + this.add(shuffledList.get(i)); + } + } + + /** Empty the list of all items. + * + */ + public void clear(){ + this.ca = new Card[10]; + this.size = 0; + } + + /** Returns true if the array is larger than the number of cards in it + * + */ + public boolean isRoom(){ + return this.ca.length > this.size; + } + + /** Copies the contents of the internal array to a new array this is twice as large + * This sets the internal array to that new array + * + */ + public void expand(){ + Card[] caNew = new Card[2*this.ca.length]; + for(int i=0; i < this.size; i++){ + caNew[i] = this.ca[i]; + } + this.ca = caNew; + } + + +} From 0cdecae35c462ca516075a495e916791266f4920 Mon Sep 17 00:00:00 2001 From: AdamZWinter Date: Wed, 11 Jan 2023 13:27:10 -0800 Subject: [PATCH 02/11] From CS145 --- src/edu/greenriver/sdev333/ArrayList.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/edu/greenriver/sdev333/ArrayList.java diff --git a/src/edu/greenriver/sdev333/ArrayList.java b/src/edu/greenriver/sdev333/ArrayList.java new file mode 100644 index 0000000..0bbafe8 --- /dev/null +++ b/src/edu/greenriver/sdev333/ArrayList.java @@ -0,0 +1,4 @@ +package edu.greenriver.sdev333; + +public class ArrayList { +} From 23fa555a50a00727e93b9eee3ca9828c72577813 Mon Sep 17 00:00:00 2001 From: AdamZWinter Date: Wed, 11 Jan 2023 14:29:08 -0800 Subject: [PATCH 03/11] From CS145 --- src/Main.java | 11 + src/edu/greenriver/sdev333/ArrayList.java | 306 +++++++++++++++++++++- 2 files changed, 316 insertions(+), 1 deletion(-) diff --git a/src/Main.java b/src/Main.java index 3e59c38..b340ab4 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,5 +1,16 @@ +import edu.greenriver.sdev333.ArrayList; +import edu.greenriver.sdev333.List; + public class Main { public static void main(String[] args) { + System.out.println("Hello world!"); + + List friends = new ArrayList(); + System.out.println("Initial size is: "+friends.size()); + + friends.add("Ehren"); + System.out.println("Size after added one: "+friends.size()); + } } \ No newline at end of file diff --git a/src/edu/greenriver/sdev333/ArrayList.java b/src/edu/greenriver/sdev333/ArrayList.java index 0bbafe8..90f62e1 100644 --- a/src/edu/greenriver/sdev333/ArrayList.java +++ b/src/edu/greenriver/sdev333/ArrayList.java @@ -1,4 +1,308 @@ package edu.greenriver.sdev333; -public class ArrayList { +import java.util.Iterator; +import java.util.ListIterator; +import java.util.Spliterator; +import java.util.function.Consumer; + +public class ArrayList implements List{ + + // one plain old java array + private ItemType[] data; + + // one int to keep track of size + // size is the spots that are used in the data array + // size is different than lenth of the array + private int size; + + public ArrayList() { + this.data = (ItemType[]) new Object[10]; + this.size = 0; + } + + /** + * Returns the number of items in this collection. + * + * @return the number of items in this collection + */ + @Override + public int size() { + return size; + } + + /** + * Returns true if this collection contains no items. + * + * @return true if this collection contains no items + */ + @Override + public boolean isEmpty() { + return false; + } + + /** + * Returns true if this collection contains the specified item. + * + * @param item items whose presence in this collection is to be tested + * @return true if this collection contains the specified item + * @throws NullPointerException if the specified item is null + * and this collection does not permit null items + */ + @Override + public boolean contains(ItemType item) { + return false; + } + + /** + * Returns an iterator over the elements in this collection. + * + * @return an Iterator over the elements in this collection + */ + @Override + public Iterator iterator() { + return null; + } + + /** + * Performs the given action for each element of the {@code Iterable} + * until all elements have been processed or the action throws an + * exception. Actions are performed in the order of iteration, if that + * order is specified. Exceptions thrown by the action are relayed to the + * caller. + *

+ * The behavior of this method is unspecified if the action performs + * side-effects that modify the underlying source of elements, unless an + * overriding class has specified a concurrent modification policy. + * + * @param action The action to be performed for each element + * @throws NullPointerException if the specified action is null + * @implSpec

The default implementation behaves as if: + *

{@code
+     *     for (T t : this)
+     *         action.accept(t);
+     * }
+ * @since 1.8 + */ + @Override + public void forEach(Consumer action) { + List.super.forEach(action); + } + + /** + * Creates a {@link Spliterator} over the elements described by this + * {@code Iterable}. + * + * @return a {@code Spliterator} over the elements described by this + * {@code Iterable}. + * @implSpec The default implementation creates an + * early-binding + * spliterator from the iterable's {@code Iterator}. The spliterator + * inherits the fail-fast properties of the iterable's iterator. + * @implNote The default implementation should usually be overridden. The + * spliterator returned by the default implementation has poor splitting + * capabilities, is unsized, and does not report any spliterator + * characteristics. Implementing classes can nearly always provide a + * better implementation. + * @since 1.8 + */ + @Override + public Spliterator spliterator() { + return List.super.spliterator(); + } + + /** + * Adds the specified item to the collection. + * + * @param item item to be added to the collection + * @throws NullPointerException if the specified item is null + * and this collection does not permit null items + */ + @Override + public void add(ItemType item) { + if(size == data.length){ + //resize up : double array size + ItemType[] temp = (ItemType[]) new Object[size * 2]; + for(int i=0; i < this.size; i++){ + temp[i] = this.data[i]; + } + this.data = temp; + temp = null; //optional : gone as soon as method closes anyway + } + data[size] = item; + size++; + + } + + /** + * Removes a single instance of the specified item from this collection, + * if it is present. + * + * @param item item to be removed from this collection, if present + * @throws NullPointerException if the specified item is null + * and this collection does not permit null items + */ + @Override + public void remove(ItemType item) { + + } + + /** + * Removes all items from this collection. + * The collection will be empty after this method returns. + */ + @Override + public void clear() { + + } + + /** + * Returns true if this collection contains all the items + * in the specified other collection. + * + * @param otherCollection collection to be checked for containment in this collection + * @return true if this collection contains all the items + * in the specified other collection + */ + @Override + public boolean containsAll(Collection otherCollection) { + return false; + } + + /** + * Adds all the items in this specified other collection to this collection. + * + * @param otherCollection collection containing items to be added to this collection + */ + @Override + public void addAll(Collection otherCollection) { + + } + + /** + * Removes all of this collection's items that are also contained in the + * specified other collection. After this call returns, this collection will + * contain no elements in common with the specified other collection. + * + * @param otherCollection collection containing elements to be removed + * from this collection + */ + @Override + public void removeAll(Collection otherCollection) { + + } + + /** + * Retains only the items in this collection that are contained in the + * specified other collection. In other words, removes from this collection + * all of its items that are not contained in the specified other collection + * + * @param otherCollection collection containing elements to be retained in + * this collection + */ + @Override + public void retainAll(Collection otherCollection) { + + } + + /** + * Returns the item at the specified position in this list + * + * @param index index of the item to return + * @return the item at the specified position in this list + * @throws IndexOutOfBoundsException if this index is out of range + * (index < 0 || index >= size()) + */ + @Override + public ItemType get(int index) { + return null; + } + + /** + * Replaces the item at the specified position in this list + * with the specified item + * + * @param index index of the item to replace + * @param item item to be stored at the specified position + * @throws NullPointerException if the specified item is null + * and this list does not permit null elements + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= size()) + */ + @Override + public void set(int index, ItemType item) { + + } + + /** + * Inserts the specified item at the specified position in this list. + * Shifts the item currently at that position (if any) and any subsequent + * items to the right. + * + * @param index index at which the specified item is to be inserted + * @param item item to be inserted + * @throws NullPointerException if the specified item is null + * and this list does not permit null elements + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= size()) + */ + @Override + public void add(int index, ItemType item) { + data[size] = item; + size++; + } + + /** + * Removes the element at the specified position in this list. + * Shifts any subsequent items to the left. + * + * @param index the index of the item to be removed + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= size()) + */ + @Override + public void remove(int index) { + + } + + /** + * Returns the index of the first occurrence of the specified item + * in this list, or -1 if this list does not contain the item. + * + * @param item the item to search for + * @return the index of the first occurrence of the specified item + * in this list, or -1 if this list does not contain the item + * @throws NullPointerException if the specified item is null and this + * list does not permit null items + */ + @Override + public int indexOf(ItemType item) { + return 0; + } + + /** + * Returns the index of the last occurrence of the specified item + * in this list, or -1 if this list does not contain the item. + * + * @param item the item to search for + * @return the index of the first occurrence of the specified item + * in this list, or -1 if this list does not contain the item + * @throws NullPointerException if the specified item is null and this + * list does not permit null items + */ + @Override + public int lastIndexOf(ItemType item) { + return 0; + } + + /** + * Returns a list iterator over the elements in this list + * (in proper sequence). + * + * @return a list iterator over the elements in this list + * (in proper sequence) + */ + @Override + public ListIterator listIterator() { + return null; + } } From 0a7621d87fc2d8ca2cf235616361f12c028cf8a8 Mon Sep 17 00:00:00 2001 From: AdamZWinter Date: Wed, 11 Jan 2023 14:49:02 -0800 Subject: [PATCH 04/11] From CS145 --- src/CardArrayList.java | 246 ---------------------- src/Main.java | 7 + src/edu/greenriver/sdev333/ArrayList.java | 26 ++- 3 files changed, 29 insertions(+), 250 deletions(-) delete mode 100644 src/CardArrayList.java diff --git a/src/CardArrayList.java b/src/CardArrayList.java deleted file mode 100644 index 950ee37..0000000 --- a/src/CardArrayList.java +++ /dev/null @@ -1,246 +0,0 @@ -import java.util.*; - -/**The CardArrayList object contains an array of Cards and povides methods for manipulating that array - * While the actual array may contain null values at indexes greater than the size of the Collection of Cards it contains, - * the public methods provided here give access to only the properties of the portion of the array that holds that Collection - * - * @author Adam Winter - * @version - */ -public class CardArrayList implements CardList -{ - - private Card[] ca; //card array - private int size; - - /** Constructor: a new CardArrayList with size 0 (zero) but an internal array with length 10 - * - */ - public CardArrayList(){ - this.ca = new Card[10]; - this.size = 0; - } - - /**Constructor: a new CardArrayList with size 0 (zero) but an internal array with length equal to the argument - * - * @param x The size to intialize the internal array - * @throws IllegalArgumentException The size of the array must be at least zero. - * - */ - public CardArrayList(int x) throws IllegalArgumentException{ - if(x < 0)throw new IllegalArgumentException("The size of the array must be at least zero."); - this.ca = new Card[x]; - this.size = 0; - } - - - /** This returns a representation of the list from index 0 to the final index. - * - * @return The string visulation of the list. - */ - public String toString(){ - String strCards = "[0: "; - for(int i = 0; i < this.size; i++){ - if(i == 0){ - strCards = strCards + ca[i].toString(); - }else{ - strCards = strCards + "," + ca[i].toString(); - } - }//end for - strCards = strCards + " :" + this.size + "]"; - return strCards; - }//end toString() - - /** This method returns the current number of elements in the list. - * Note, this is not the length of the interal array, but the number of Cards in the collection - * - * @return the size of the list as an integer - */ - public int size(){ - return this.size; - } - - - /** This method adds a card to the end of the list in the first available spot. - * The size of the internal array is checked first, and expanded if there is not room - * - * @param c the Card object to be added. - */ - public void add(Card c){ - if(!this.isRoom()){ - this.expand(); - this.ca[this.size] = c; - this.size++; - }else{ - this.ca[this.size] = c; - this.size++; - } - } - - - /** This adds a card to the indicated location, per the given argument, sliding all other elements over one. - * - * @param loc the desired index of the card to be added. - * @param c the Card object to be added. - * @throws IndexOutOfBoundsException if the loc is outside the current list. - */ - public void add(int loc, Card c) throws IndexOutOfBoundsException { - if(loc < 0 || loc > this.size) throw new IndexOutOfBoundsException("Index out of bounds in call to add(int, Card)"); - if(!this.isRoom()){ - this.expand(); - for(int i = this.size; i >= loc + 1; i--){ - this.ca[i] = this.ca[i - 1]; - } - this.ca[loc] = c; - this.size++; - }else{ - for(int i = this.size; i >= loc + 1; i--){ - this.ca[i] = this.ca[i - 1]; - } - this.ca[loc] = c; - this.size++; - } - }//end add - - - /** This method removes the last element from the list, and returns it. - * - * @return The card object removed from the list. - * @throws IndexOutOfBoundsException if the list is empty. - */ - public Card remove() throws IndexOutOfBoundsException { - if(this.size == 0)throw new IndexOutOfBoundsException("The list is empty, but you called remove()."); - this.size--; - return this.ca[this.size]; - } - - /** This removes the identified card from the list and return it. - * The remain cards to the right then slide the the left - * - * @param loc the index of the card to be removed. - * @return The card object removed from the list. - * @throws IndexOutOfBoundsException if the loc is outside the current array size. - */ - public Card remove(int loc) throws IndexOutOfBoundsException { - if(loc < 0 || loc >= this.size) throw new IndexOutOfBoundsException("Index out of bounds in call to remove(int)."); - Card requested = this.ca[loc]; - for (int i = loc; i < this.size - 1; i++){ - this.ca[i] = this.ca[i + 1]; - } - this.size--; - return requested; - } - - /** This returns the element from the list that is the index provided as the argument - * - * @param i The index of the desired card. - * @return The card object locatated in index x from the list. - * @throws IndexOutOfBoundsException if the i value is outside the range of the list - */ - public Card get(int i) throws IndexOutOfBoundsException{ - if(i < 0 || i >= this.size) throw new IndexOutOfBoundsException("Index is out of bounds in call to get()."); - return this.ca[i]; - }//end get - - /** Returns the index of specified Card object - * - * @param c Card object - * @return index of Card otherwise -1 if not found - */ - public int indexOf(Card c){ - for (int i = 0; i < size; i++){ - if(this.ca[i].equals(c)){ - return i; - } - } - return -1; - } - - /** Sort the items in the list from smallest to largest - * - */ - public void sort(){ - if(this.size < 2)return; - Card[] exact = new Card[this.size]; //learned this lesson the long and hard way - for(int i = 0; i < this.size; i++){ // Before the list can be sorted, the null positions in the array are removed - exact[i] = this.ca[i]; // This is done by copying all the Cards into an array of the exact size needed - } - this.ca = exact; //The main/internal array that hold the collection is then set to the new array - mergeSort(this.ca); //And then it is sorted - } - - //standard mergeSort using recursion - private void mergeSort(Card[] ca){ - if(ca.length > 1){ - Card[] left = Arrays.copyOfRange(ca, 0, ca.length/2); - Card[] right = Arrays.copyOfRange(ca, ca.length/2, ca.length); - mergeSort(left); - mergeSort(right); - merge(ca, left, right); - }//end if - }//end mergeSort - - //standard merge for a mergeSort - private void merge(Card[] result, Card[] left, Card[] right){ - int i1 = 0; - int i2 = 0; - for(int i = 0; i < result.length; i++){ //started by taking this directly from the book - if(i2 >= right.length) { - result[i] = left[i1]; - i1++; - }else if(i1 >= left.length) { //split this into pieces while troubleshooting the problem I was having before I realized - result[i] = right[i2]; //that the array needed to be trimmed of the null values to the exact size - i2++; //otherwise you end up trying to sort null values - }else if(left[i1].compareTo(right[i2]) < 0){ //this is the line where the null valus first become a problem - result[i] = left[i1]; - i1++; - }else{ - result[i] = right[i2]; - i2++; - } - }//end for - }//end merge - - /** Not such a weak shuffle algorithm; Shuffles the collection of Cards - * - */ - public void shuffle(){ - CardList shuffledList = new CardArrayList(this.size); //create a new CardArrayList - Random rand = new Random(); - for(int i = this.size - 1; i >= 0; i--){ - shuffledList.add(this.remove(rand.nextInt(i + 1))); //randomly remove cards from the original List and add them to the new one - } - for(int i = 0; i < shuffledList.size(); i++){ //put all the cards back into the original List in the new shuffled order - this.add(shuffledList.get(i)); - } - } - - /** Empty the list of all items. - * - */ - public void clear(){ - this.ca = new Card[10]; - this.size = 0; - } - - /** Returns true if the array is larger than the number of cards in it - * - */ - public boolean isRoom(){ - return this.ca.length > this.size; - } - - /** Copies the contents of the internal array to a new array this is twice as large - * This sets the internal array to that new array - * - */ - public void expand(){ - Card[] caNew = new Card[2*this.ca.length]; - for(int i=0; i < this.size; i++){ - caNew[i] = this.ca[i]; - } - this.ca = caNew; - } - - -} diff --git a/src/Main.java b/src/Main.java index b340ab4..834ec54 100644 --- a/src/Main.java +++ b/src/Main.java @@ -12,5 +12,12 @@ public static void main(String[] args) { friends.add("Ehren"); System.out.println("Size after added one: "+friends.size()); + for(int i = 0; i < 50; i++){ + friends.add("Friend"+i); + } + System.out.println("Size after many added: "+friends.size()); + System.out.println(friends); + + } } \ No newline at end of file diff --git a/src/edu/greenriver/sdev333/ArrayList.java b/src/edu/greenriver/sdev333/ArrayList.java index 90f62e1..b59d5f0 100644 --- a/src/edu/greenriver/sdev333/ArrayList.java +++ b/src/edu/greenriver/sdev333/ArrayList.java @@ -150,6 +150,16 @@ public void remove(ItemType item) { * Removes all items from this collection. * The collection will be empty after this method returns. */ + + @Override + public String toString(){ + String output = "["; + for(int i=0; i < size-1; i++){ + output = output + data[i].toString() +", "; + } + output = output + data[size-1].toString() +"]"; + return output; + } @Override public void clear() { @@ -165,7 +175,8 @@ public void clear() { */ @Override public boolean containsAll(Collection otherCollection) { - return false; + //fail fast (fail loud) + throw new UnsupportedOperationException("containsAll method is not supported in this implementation"); } /** @@ -175,7 +186,8 @@ public boolean containsAll(Collection otherCollection) { */ @Override public void addAll(Collection otherCollection) { - + //fail fast (fail loud) + throw new UnsupportedOperationException("addAll method is not supported in this implementation"); } /** @@ -214,7 +226,10 @@ public void retainAll(Collection otherCollection) { */ @Override public ItemType get(int index) { - return null; + if(index >= size){ + throw new IndexOutOfBoundsException("index is out of bounds"); + } + return data[index]; } /** @@ -230,7 +245,10 @@ public ItemType get(int index) { */ @Override public void set(int index, ItemType item) { - + if(index >= size){ + throw new IndexOutOfBoundsException("index is out of bounds"); + } + data[index] = item; } /** From 7d9c0a73ebef1f046921aa0bc34d5aebb2942c7b Mon Sep 17 00:00:00 2001 From: AdamZWinter Date: Wed, 18 Jan 2023 13:44:35 -0800 Subject: [PATCH 05/11] adding iterators --- src/Main.java | 13 ++ src/edu/greenriver/sdev333/ArrayList.java | 196 +++++++++++++++++++++- 2 files changed, 208 insertions(+), 1 deletion(-) diff --git a/src/Main.java b/src/Main.java index 834ec54..98c39a5 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,6 +1,8 @@ import edu.greenriver.sdev333.ArrayList; import edu.greenriver.sdev333.List; +import java.util.Iterator; + public class Main { public static void main(String[] args) { @@ -18,6 +20,17 @@ public static void main(String[] args) { System.out.println("Size after many added: "+friends.size()); System.out.println(friends); + System.out.print(System.lineSeparator()); + Iterator itr = friends.iterator(); + while(itr.hasNext()){ + String name = itr.next(); + System.out.print(name+" "); + } + + System.out.print(System.lineSeparator()); + for(String name : friends){ + System.out.print(name+ " "); + } } } \ No newline at end of file diff --git a/src/edu/greenriver/sdev333/ArrayList.java b/src/edu/greenriver/sdev333/ArrayList.java index b59d5f0..da3e248 100644 --- a/src/edu/greenriver/sdev333/ArrayList.java +++ b/src/edu/greenriver/sdev333/ArrayList.java @@ -60,7 +60,7 @@ public boolean contains(ItemType item) { */ @Override public Iterator iterator() { - return null; + return new MyCustomIterator(); } /** @@ -323,4 +323,198 @@ public int lastIndexOf(ItemType item) { public ListIterator listIterator() { return null; } + + private class MyCustomIterator implements Iterator{ + + private int currentPosition; + public MyCustomIterator(){ + currentPosition = 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 currentPosition < 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 ItemType next() { + return get(currentPosition++); + } + } + + private class MyCustomListIterator implements ListIterator{ + private int currentPosition; + public MyCustomListIterator(){ + currentPosition = 0; + } + + /** + * Returns {@code true} if this list iterator has more elements when + * traversing the list in the forward direction. (In other words, + * returns {@code true} if {@link #next} would return an element rather + * than throwing an exception.) + * + * @return {@code true} if the list iterator has more elements when + * traversing the list in the forward direction + */ + @Override + public boolean hasNext() { + return false; + } + + /** + * Returns the next element in the list and advances the cursor position. + * This method may be called repeatedly to iterate through the list, + * or intermixed with calls to {@link #previous} to go back and forth. + * (Note that alternating calls to {@code next} and {@code previous} + * will return the same element repeatedly.) + * + * @return the next element in the list + * @throws NoSuchElementException if the iteration has no next element + */ + @Override + public ItemType next() { + return null; + } + + /** + * Returns {@code true} if this list iterator has more elements when + * traversing the list in the reverse direction. (In other words, + * returns {@code true} if {@link #previous} would return an element + * rather than throwing an exception.) + * + * @return {@code true} if the list iterator has more elements when + * traversing the list in the reverse direction + */ + @Override + public boolean hasPrevious() { + return currentPosition > 0; + } + + /** + * Returns the previous element in the list and moves the cursor + * position backwards. This method may be called repeatedly to + * iterate through the list backwards, or intermixed with calls to + * {@link #next} to go back and forth. (Note that alternating calls + * to {@code next} and {@code previous} will return the same + * element repeatedly.) + * + * @return the previous element in the list + * @throws NoSuchElementException if the iteration has no previous + * element + */ + @Override + public ItemType previous() { + return null; + } + + /** + * Returns the index of the element that would be returned by a + * subsequent call to {@link #next}. (Returns list size if the list + * iterator is at the end of the list.) + * + * @return the index of the element that would be returned by a + * subsequent call to {@code next}, or list size if the list + * iterator is at the end of the list + */ + @Override + public int nextIndex() { + return 0; + } + + /** + * Returns the index of the element that would be returned by a + * subsequent call to {@link #previous}. (Returns -1 if the list + * iterator is at the beginning of the list.) + * + * @return the index of the element that would be returned by a + * subsequent call to {@code previous}, or -1 if the list + * iterator is at the beginning of the list + */ + @Override + public int previousIndex() { + return 0; + } + + /** + * Removes from the list the last element that was returned by {@link + * #next} or {@link #previous} (optional operation). This call can + * only be made once per call to {@code next} or {@code previous}. + * It can be made only if {@link #add} has not been + * called after the last call to {@code next} or {@code previous}. + * + * @throws UnsupportedOperationException if the {@code remove} + * operation is not supported by this list iterator + * @throws IllegalStateException if neither {@code next} nor + * {@code previous} have been called, or {@code remove} or + * {@code add} have been called after the last call to + * {@code next} or {@code previous} + */ + @Override + public void remove() { + + } + + /** + * Replaces the last element returned by {@link #next} or + * {@link #previous} with the specified element (optional operation). + * This call can be made only if neither {@link #remove} nor {@link + * #add} have been called after the last call to {@code next} or + * {@code previous}. + * + * @param itemType the element with which to replace the last element returned by + * {@code next} or {@code previous} + * @throws UnsupportedOperationException if the {@code set} operation + * is not supported by this list iterator + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this list + * @throws IllegalArgumentException if some aspect of the specified + * element prevents it from being added to this list + * @throws IllegalStateException if neither {@code next} nor + * {@code previous} have been called, or {@code remove} or + * {@code add} have been called after the last call to + * {@code next} or {@code previous} + */ + @Override + public void set(ItemType itemType) { + + } + + /** + * Inserts the specified element into the list (optional operation). + * The element is inserted immediately before the element that + * would be returned by {@link #next}, if any, and after the element + * that would be returned by {@link #previous}, if any. (If the + * list contains no elements, the new element becomes the sole element + * on the list.) The new element is inserted before the implicit + * cursor: a subsequent call to {@code next} would be unaffected, and a + * subsequent call to {@code previous} would return the new element. + * (This call increases by one the value that would be returned by a + * call to {@code nextIndex} or {@code previousIndex}.) + * + * @param itemType the element to insert + * @throws UnsupportedOperationException if the {@code add} method is + * not supported by this list iterator + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this list + * @throws IllegalArgumentException if some aspect of this element + * prevents it from being added to this list + */ + @Override + public void add(ItemType itemType) { + + } + } } From a6de6d7ca5ef932b57700fbdec34ef9f154ed3b6 Mon Sep 17 00:00:00 2001 From: AdamZWinter Date: Wed, 18 Jan 2023 16:05:33 -0800 Subject: [PATCH 06/11] Methods written, still need testing --- src/Main.java | 6 + src/edu/greenriver/sdev333/ArrayList.java | 182 +++++++++++++--------- 2 files changed, 118 insertions(+), 70 deletions(-) diff --git a/src/Main.java b/src/Main.java index 98c39a5..6fa4692 100644 --- a/src/Main.java +++ b/src/Main.java @@ -10,6 +10,7 @@ public static void main(String[] args) { List friends = new ArrayList(); System.out.println("Initial size is: "+friends.size()); + System.out.println("List is empty: " + friends.isEmpty()); friends.add("Ehren"); System.out.println("Size after added one: "+friends.size()); @@ -18,6 +19,11 @@ public static void main(String[] args) { friends.add("Friend"+i); } System.out.println("Size after many added: "+friends.size()); + + System.out.println(friends.contains("Friend1")); + System.out.println(friends.contains("Friendx")); + + System.out.println(friends); System.out.print(System.lineSeparator()); diff --git a/src/edu/greenriver/sdev333/ArrayList.java b/src/edu/greenriver/sdev333/ArrayList.java index da3e248..1b9a5f6 100644 --- a/src/edu/greenriver/sdev333/ArrayList.java +++ b/src/edu/greenriver/sdev333/ArrayList.java @@ -2,6 +2,7 @@ import java.util.Iterator; import java.util.ListIterator; +import java.util.Objects; import java.util.Spliterator; import java.util.function.Consumer; @@ -15,11 +16,41 @@ public class ArrayList implements List{ // size is different than lenth of the array private int size; + //Constructor public ArrayList() { this.data = (ItemType[]) new Object[10]; this.size = 0; } + //Constructor + public ArrayList(int capacity) { + this.data = (ItemType[]) new Object[capacity]; + this.size = 0; + } + + + /** returns hashcode for this object by hashing toString with Objects.hash + * + * @return int hashcode + */ + public int hashcode(){ + return Objects.hash(this.toString()); + } + + @Override + public boolean equals(Object other){ + return (other instanceof ArrayList) && ((ArrayList) other).hashcode() == hashcode(); + } + + + private void trimArray(){ + ItemType[] tempArray = (ItemType[]) new Object[size]; + for(int i = 0; i < size; i++){ + tempArray[i] = data[i]; + } + data = tempArray; + } + /** * Returns the number of items in this collection. * @@ -37,7 +68,7 @@ public int size() { */ @Override public boolean isEmpty() { - return false; + return size == 0; } /** @@ -50,7 +81,8 @@ public boolean isEmpty() { */ @Override public boolean contains(ItemType item) { - return false; + int index = indexOf(item); + return isValidIndex(index); } /** @@ -63,52 +95,6 @@ public Iterator iterator() { return new MyCustomIterator(); } - /** - * Performs the given action for each element of the {@code Iterable} - * until all elements have been processed or the action throws an - * exception. Actions are performed in the order of iteration, if that - * order is specified. Exceptions thrown by the action are relayed to the - * caller. - *

- * The behavior of this method is unspecified if the action performs - * side-effects that modify the underlying source of elements, unless an - * overriding class has specified a concurrent modification policy. - * - * @param action The action to be performed for each element - * @throws NullPointerException if the specified action is null - * @implSpec

The default implementation behaves as if: - *

{@code
-     *     for (T t : this)
-     *         action.accept(t);
-     * }
- * @since 1.8 - */ - @Override - public void forEach(Consumer action) { - List.super.forEach(action); - } - - /** - * Creates a {@link Spliterator} over the elements described by this - * {@code Iterable}. - * - * @return a {@code Spliterator} over the elements described by this - * {@code Iterable}. - * @implSpec The default implementation creates an - * early-binding - * spliterator from the iterable's {@code Iterator}. The spliterator - * inherits the fail-fast properties of the iterable's iterator. - * @implNote The default implementation should usually be overridden. The - * spliterator returned by the default implementation has poor splitting - * capabilities, is unsized, and does not report any spliterator - * characteristics. Implementing classes can nearly always provide a - * better implementation. - * @since 1.8 - */ - @Override - public Spliterator spliterator() { - return List.super.spliterator(); - } /** * Adds the specified item to the collection. @@ -119,20 +105,31 @@ public Spliterator spliterator() { */ @Override public void add(ItemType item) { - if(size == data.length){ - //resize up : double array size - ItemType[] temp = (ItemType[]) new Object[size * 2]; - for(int i=0; i < this.size; i++){ - temp[i] = this.data[i]; - } - this.data = temp; - temp = null; //optional : gone as soon as method closes anyway + if(!hasRoom()){ + expand(); } data[size] = item; size++; } + private boolean hasRoom(){ + return size != data.length; + } + + private void expand(){ + //resize up : double array size + ItemType[] temp = (ItemType[]) new Object[size * 2]; + for(int i=0; i < this.size; i++){ + temp[i] = this.data[i]; + } + this.data = temp; + } + + private boolean isValidIndex(int index){ + return index >= 0 && index < size && size !=0; + } + /** * Removes a single instance of the specified item from this collection, * if it is present. @@ -143,7 +140,16 @@ public void add(ItemType item) { */ @Override public void remove(ItemType item) { - + int tempSize = 0; + ItemType[] tempData = (ItemType[]) new Object[size]; + for(int i =0; i < size; i++){ + if(!item.equals(data[i])){ + tempData[tempSize] = data[i]; + tempSize++; + } + } + data = tempData; + size = tempSize; } /** @@ -162,7 +168,8 @@ public String toString(){ } @Override public void clear() { - + this.data = (ItemType[]) new Object[10]; + this.size = 0; } /** @@ -176,7 +183,16 @@ public void clear() { @Override public boolean containsAll(Collection otherCollection) { //fail fast (fail loud) - throw new UnsupportedOperationException("containsAll method is not supported in this implementation"); + //throw new UnsupportedOperationException("containsAll method is not supported in this implementation"); + + Iterator itr = (Iterator)otherCollection.iterator(); + while(itr.hasNext()){ + ItemType itemToCheck = itr.next(); + if(!contains(itemToCheck)){ + return false; + } + } + return true; } /** @@ -187,7 +203,10 @@ public boolean containsAll(Collection otherCollection) { @Override public void addAll(Collection otherCollection) { //fail fast (fail loud) - throw new UnsupportedOperationException("addAll method is not supported in this implementation"); + //throw new UnsupportedOperationException("addAll method is not supported in this implementation"); + for(ItemType other : otherCollection){ + add(other); + } } /** @@ -200,7 +219,8 @@ public void addAll(Collection otherCollection) { */ @Override public void removeAll(Collection otherCollection) { - + //fail fast (fail loud) + throw new UnsupportedOperationException("addAll method is not supported in this implementation"); } /** @@ -213,7 +233,8 @@ public void removeAll(Collection otherCollection) { */ @Override public void retainAll(Collection otherCollection) { - + //fail fast (fail loud) + throw new UnsupportedOperationException("addAll method is not supported in this implementation"); } /** @@ -226,7 +247,7 @@ public void retainAll(Collection otherCollection) { */ @Override public ItemType get(int index) { - if(index >= size){ + if(!isValidIndex(index)){ throw new IndexOutOfBoundsException("index is out of bounds"); } return data[index]; @@ -245,7 +266,7 @@ public ItemType get(int index) { */ @Override public void set(int index, ItemType item) { - if(index >= size){ + if(!isValidIndex(index)){ throw new IndexOutOfBoundsException("index is out of bounds"); } data[index] = item; @@ -265,8 +286,14 @@ public void set(int index, ItemType item) { */ @Override public void add(int index, ItemType item) { - data[size] = item; - size++; + if(index > size || index < 0){ + throw new IndexOutOfBoundsException("index is out of bounds"); + } + if(!hasRoom()){expand();} + for(int i = size; i>index; i--){ + data[i] = data[i-1]; + } + data[index] = item; } /** @@ -279,7 +306,12 @@ public void add(int index, ItemType item) { */ @Override public void remove(int index) { - + if(!isValidIndex(index)){throw new IndexOutOfBoundsException("Index out of bounds");} + //shift values left to overwrite the item at index + for(int i = index; i= 0; i--){ + if(item.equals(data[i])){ + return i; + } + } + return -1; } /** @@ -321,7 +363,7 @@ public int lastIndexOf(ItemType item) { */ @Override public ListIterator listIterator() { - return null; + return new MyCustomListIterator(); } private class MyCustomIterator implements Iterator{ From 271ac495e8dd264490d15c4a3c888a08ef523efd Mon Sep 17 00:00:00 2001 From: AdamZWinter Date: Wed, 18 Jan 2023 16:48:47 -0800 Subject: [PATCH 07/11] Testing good, but need to finish List Iterator --- ImplementingLists.iml | 27 +++ src/edu/greenriver/sdev333/ArrayList.java | 12 +- .../edu/greenriver/sdev333/ArrayListTest.java | 166 ++++++++++++++++++ 3 files changed, 200 insertions(+), 5 deletions(-) create mode 100644 tests/edu/greenriver/sdev333/ArrayListTest.java diff --git a/ImplementingLists.iml b/ImplementingLists.iml index c90834f..9c8bf10 100644 --- a/ImplementingLists.iml +++ b/ImplementingLists.iml @@ -4,8 +4,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/edu/greenriver/sdev333/ArrayList.java b/src/edu/greenriver/sdev333/ArrayList.java index 1b9a5f6..88fa03e 100644 --- a/src/edu/greenriver/sdev333/ArrayList.java +++ b/src/edu/greenriver/sdev333/ArrayList.java @@ -413,7 +413,7 @@ public MyCustomListIterator(){ */ @Override public boolean hasNext() { - return false; + return currentPosition < size(); } /** @@ -428,7 +428,7 @@ public boolean hasNext() { */ @Override public ItemType next() { - return null; + return get(currentPosition++); } /** @@ -459,7 +459,9 @@ public boolean hasPrevious() { */ @Override public ItemType previous() { - return null; + ItemType returnThis = get(currentPosition -1); + currentPosition--; + return returnThis; } /** @@ -473,7 +475,7 @@ public ItemType previous() { */ @Override public int nextIndex() { - return 0; + return currentPosition; } /** @@ -487,7 +489,7 @@ public int nextIndex() { */ @Override public int previousIndex() { - return 0; + return currentPosition - 1; } /** diff --git a/tests/edu/greenriver/sdev333/ArrayListTest.java b/tests/edu/greenriver/sdev333/ArrayListTest.java new file mode 100644 index 0000000..4ccaa06 --- /dev/null +++ b/tests/edu/greenriver/sdev333/ArrayListTest.java @@ -0,0 +1,166 @@ +package edu.greenriver.sdev333; + +import java.util.Iterator; + +import static org.junit.jupiter.api.Assertions.*; + +class ArrayListTest { + + ArrayList testListOne = new ArrayList<>(5); + ArrayList testListTwo = new ArrayList<>(2); + + @org.junit.jupiter.api.Test + void testEquals() { + testListOne.add("foo"); + testListTwo.add("foo"); + assertEquals(true, testListOne.equals(testListTwo)); + testListOne.add("bar"); + assertEquals(false, testListOne.equals(testListTwo)); + } + + @org.junit.jupiter.api.Test + void size() { + testListOne.add("bar"); + testListOne.add("foo"); + assertEquals(2, testListOne.size()); + } + + @org.junit.jupiter.api.Test + void isEmpty() { + assertEquals(true, testListOne.isEmpty()); + testListOne.add("one"); + assertEquals(false, testListOne.isEmpty()); + } + + @org.junit.jupiter.api.Test + void contains() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + assertEquals(true, testListOne.contains("foo")); + assertEquals(false, testListOne.contains("nope")); + } + + @org.junit.jupiter.api.Test + void iterator() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + Iterator itr = testListOne.iterator(); + assertEquals(true, itr instanceof Iterator); + assertEquals("one", itr.next()); + assertEquals("bar", itr.next()); + assertEquals(true, itr.hasNext()); + assertEquals("foo", itr.next()); + assertEquals(false, itr.hasNext()); + } + + @org.junit.jupiter.api.Test + void add() { + //trivial : included with other tests + } + + @org.junit.jupiter.api.Test + void remove() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + testListOne.remove(1); + assertEquals("foo", testListOne.get(1)); + } + + @org.junit.jupiter.api.Test + void testToString() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + assertEquals("[one, bar, foo]", testListOne.toString()); + } + + @org.junit.jupiter.api.Test + void clear() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + testListOne.clear(); + assertEquals(true, testListOne.isEmpty()); + assertEquals(0, testListOne.size()); + } + + @org.junit.jupiter.api.Test + void containsAll() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + testListOne.add("more"); + testListOne.add("stuff"); + testListOne.add("now"); + + testListTwo.add("bar"); + testListTwo.add("foo"); + + assertEquals(true, testListOne.containsAll(testListTwo)); + + testListTwo.add("nope"); + assertEquals(false, testListOne.containsAll(testListTwo)); + + } + + @org.junit.jupiter.api.Test + void addAll() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + + testListTwo.add("more"); + testListTwo.add("stuff"); + + testListOne.addAll(testListTwo); + assertEquals("[one, bar, foo, more, stuff]", testListOne.toString()); + } + + @org.junit.jupiter.api.Test + void get() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + assertEquals("foo", testListOne.get(2)); + } + + @org.junit.jupiter.api.Test + void set() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + assertEquals("foo", testListOne.get(2)); + testListOne.set(2, "new"); + assertEquals("new", testListOne.get(2)); + } + + @org.junit.jupiter.api.Test + void indexOf() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + testListOne.add("new"); + assertEquals(3, testListOne.indexOf("new")); + } + + @org.junit.jupiter.api.Test + void lastIndexOf() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + testListOne.add("new"); + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + testListOne.add("new"); + assertEquals(2, testListOne.indexOf("foo")); + assertEquals(6, testListOne.lastIndexOf("foo")); + } + + @org.junit.jupiter.api.Test + void listIterator() { + } +} \ No newline at end of file From 06bc1bacc5fc134596f90694fdb7bc907ab313b3 Mon Sep 17 00:00:00 2001 From: AdamZWinter Date: Thu, 19 Jan 2023 20:06:59 -0800 Subject: [PATCH 08/11] all tests passing --- .idea/vcs.xml | 6 +++ src/edu/greenriver/sdev333/ArrayList.java | 42 ++++++++++++++----- .../edu/greenriver/sdev333/ArrayListTest.java | 39 +++++++++++++++++ 3 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 .idea/vcs.xml diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/edu/greenriver/sdev333/ArrayList.java b/src/edu/greenriver/sdev333/ArrayList.java index 88fa03e..7a04d44 100644 --- a/src/edu/greenriver/sdev333/ArrayList.java +++ b/src/edu/greenriver/sdev333/ArrayList.java @@ -1,9 +1,6 @@ package edu.greenriver.sdev333; -import java.util.Iterator; -import java.util.ListIterator; -import java.util.Objects; -import java.util.Spliterator; +import java.util.*; import java.util.function.Consumer; public class ArrayList implements List{ @@ -398,8 +395,10 @@ public ItemType next() { private class MyCustomListIterator implements ListIterator{ private int currentPosition; + private int lastIndex; public MyCustomListIterator(){ currentPosition = 0; + lastIndex = -1; } /** @@ -428,6 +427,7 @@ public boolean hasNext() { */ @Override public ItemType next() { + lastIndex = currentPosition; return get(currentPosition++); } @@ -459,6 +459,10 @@ public boolean hasPrevious() { */ @Override public ItemType previous() { + if(currentPosition - 1 < 0){ + throw new NoSuchElementException("You are at the beginning of the list"); + } + lastIndex = currentPosition - 1; ItemType returnThis = get(currentPosition -1); currentPosition--; return returnThis; @@ -508,7 +512,15 @@ public int previousIndex() { */ @Override public void remove() { - + if(lastIndex == -1){ + throw new IllegalStateException("You can only call remove() once after next() or previous() and not after add()"); + } + for(int i = lastIndex; ilastIndex; i--){ + data[i] = data[i-1]; + } + data[lastIndex] = item; + lastIndex = -1; } } } diff --git a/tests/edu/greenriver/sdev333/ArrayListTest.java b/tests/edu/greenriver/sdev333/ArrayListTest.java index 4ccaa06..28d9d60 100644 --- a/tests/edu/greenriver/sdev333/ArrayListTest.java +++ b/tests/edu/greenriver/sdev333/ArrayListTest.java @@ -1,6 +1,7 @@ package edu.greenriver.sdev333; import java.util.Iterator; +import java.util.ListIterator; import static org.junit.jupiter.api.Assertions.*; @@ -162,5 +163,43 @@ void lastIndexOf() { @org.junit.jupiter.api.Test void listIterator() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + testListOne.add("more"); + testListOne.add("stuff"); + + ListIterator itr = testListOne.listIterator(); + assertEquals("one", itr.next()); + assertEquals("bar", itr.next()); + assertEquals(true, itr.hasNext()); + assertEquals("foo", itr.next()); + assertEquals("foo", itr.previous()); + assertEquals("bar", itr.previous()); + assertEquals(true, itr.hasPrevious()); + assertEquals("one", itr.previous()); + assertEquals(false, itr.hasPrevious()); + assertEquals("one", itr.next()); + assertEquals(true, itr.hasNext()); + assertEquals("bar", itr.next()); + assertEquals("foo", itr.next()); + assertEquals("more", itr.next()); + assertEquals("stuff", itr.next()); + assertEquals(false, itr.hasNext()); + assertEquals("stuff", itr.previous()); + assertEquals(4, itr.nextIndex()); + assertEquals(3, itr.previousIndex()); + assertEquals("stuff", itr.next()); + itr.remove(); + assertEquals("more", itr.previous()); + itr.set("less"); + assertEquals("less", itr.next()); + assertEquals(false, itr.hasNext()); + itr.add("time"); + assertEquals(false, itr.hasNext()); + assertEquals("time", itr.previous()); + assertEquals("foo", itr.previous()); + + } } \ No newline at end of file From 7470576ff1fbcf4f82f3f043879f1cf192586ff1 Mon Sep 17 00:00:00 2001 From: AdamZWinter Date: Mon, 23 Jan 2023 17:27:27 -0800 Subject: [PATCH 09/11] All methods written, still need tests --- .idea/uiDesigner.xml | 124 ++++++ src/edu/greenriver/sdev333/ArrayList.java | 10 +- .../greenriver/sdev333/DoublyLinkedList.java | 420 ++++++++++++++++++ src/edu/greenriver/sdev333/List.java | 5 +- 4 files changed, 553 insertions(+), 6 deletions(-) create mode 100644 .idea/uiDesigner.xml create mode 100644 src/edu/greenriver/sdev333/DoublyLinkedList.java diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/edu/greenriver/sdev333/ArrayList.java b/src/edu/greenriver/sdev333/ArrayList.java index 7a04d44..97c700d 100644 --- a/src/edu/greenriver/sdev333/ArrayList.java +++ b/src/edu/greenriver/sdev333/ArrayList.java @@ -1,7 +1,6 @@ package edu.greenriver.sdev333; import java.util.*; -import java.util.function.Consumer; public class ArrayList implements List{ @@ -30,13 +29,14 @@ public ArrayList(int capacity) { * * @return int hashcode */ - public int hashcode(){ + @Override + public int hashCode(){ return Objects.hash(this.toString()); } @Override public boolean equals(Object other){ - return (other instanceof ArrayList) && ((ArrayList) other).hashcode() == hashcode(); + return (other instanceof ArrayList) && ((ArrayList) other).hashCode() == hashCode(); } @@ -298,17 +298,19 @@ public void add(int index, ItemType item) { * Shifts any subsequent items to the left. * * @param index the index of the item to be removed + * @return * @throws IndexOutOfBoundsException if the index is out of range * (index < 0 || index >= size()) */ @Override - public void remove(int index) { + public ItemType remove(int index) { if(!isValidIndex(index)){throw new IndexOutOfBoundsException("Index out of bounds");} //shift values left to overwrite the item at index for(int i = index; i implements List { + + + private Node head; + private Node tail; + private int size; + + public DoublyLinkedList(){ + //an empty list has no nodes + //which means it ahs no head, so set head to null + this.head = null; + this.tail = null; + this.size = 0; + } + + /** + * @return + */ + @Override + public int size() { + return size; + } + + /** + * @return + */ + @Override + public boolean isEmpty() { + return size == 0; + } + + /** + * @param item items whose presence in this collection is to be tested + * @return + */ + @Override + public boolean contains(ItemType item) { + int index = indexOf(item); + return index != -1; + } + + /** + * @return + */ + @Override + public Iterator iterator() { + return new myTwoWayIterator(); + } + + /** + * @param item item to be added to the collection + */ + @Override + public void add(ItemType item) { + Node looseNode = new Node(item); + if(this.head == null){ + this.head = looseNode; + this.tail = looseNode; + this.size++; + }else{ + looseNode.prev = this.tail; + this.tail.next = looseNode; + this.tail = looseNode; + this.size++; + } + } + + /** + * @param item item to be removed from this collection, if present + */ + @Override + public void remove(ItemType item) { + int index = indexOf(item); + if(index != -1){ + remove(index); + } + } + + public int remove(ItemType item, boolean returnIndex) { + int index = indexOf(item); + if(index != -1){ + remove(index); + } + return index; + } + + public void removeEvery(ItemType item){ + if(remove(item, true) != -1){ + removeEvery(item); + } + } + + /** + * + */ + @Override + public void clear() { + head = null; + size = 0; + } + + /** + * @param otherCollection collection to be checked for containment in this collection + * @return + */ + @Override + public boolean containsAll(Collection otherCollection) { + throw new UnsupportedOperationException("The containsAll() method is not implemented here."); + } + + /** + * @param otherCollection collection containing items to be added to this collection + */ + @Override + public void addAll(Collection otherCollection) { + for(ItemType other : otherCollection){ + add(other); + } + } + + /** + * @param otherCollection collection containing elements to be removed + * from this collection + */ + @Override + public void removeAll(Collection otherCollection) { + for(ItemType other : otherCollection){ + removeEvery(other); + } + } + + /** + * @param otherCollection collection containing elements to be retained in + * this collection + */ + @Override + public void retainAll(Collection otherCollection) { + throw new UnsupportedOperationException("The retailAll() method is not implemented here."); + } + + /** + * @param i index of the item to return + * @return + */ + @Override + public ItemType get(int i) { + if(i < 0 || i >= this.size) throw new IndexOutOfBoundsException("Index out of bounds in call to get(int)."); + Node current = this.head; + for(int j = 0; j < i; j++){ + current = current.next; + } + return current.data; + } + + /** + * @param i index of the item to replace + * @param item item to be stored at the specified position + */ + @Override + public void set(int i, ItemType item) { + if(i < 0 || i >= this.size) throw new IndexOutOfBoundsException("Index out of bounds in call to get(int)."); + Node current = this.head; + for(int j = 0; j < i; j++){ + current = current.next; + } + current.data = item; + } + + /** + * @param index index at which the specified item is to be inserted + * @param item item to be inserted + */ + @Override + public void add(int index, ItemType item) { + if(index < 0 || index > this.size) throw new IndexOutOfBoundsException("IndexOutOfBounds in call to add(int, ItemType)"); + Node looseNode = new Node(item); + if(this.head == null){ + this.head = looseNode; + this.tail = looseNode; + this.size = 1; + }else if(index == 0){ + looseNode.next = this.head; + this.head = looseNode; + this.size++; + }else if(index == this.size){ + this.add(item); + }else{ + Node current = this.head; + for(int i = 0; i < index - 1; i++){ + current = current.next; + } + current.next.prev = looseNode; + looseNode.next = current.next; + looseNode.prev = current; + current.next = looseNode; + this.size++; + } + } + + /** This method removes the last element from the list, and returns it. + * + * @return The object removed from the list. + * @throws IndexOutOfBoundsException if the list is empty. + */ + public ItemType remove() throws IndexOutOfBoundsException { + if(this.size == 0)throw new IndexOutOfBoundsException("The list is empty, but you called remove()."); + if(this.size == 1){ + Node lastOne = this.head; + this.head = null; + this.tail = null; + this.size = 0; + return lastOne.data; + }else{ + Node end = this.tail; + this.tail = this.tail.prev; //There is no previous, if this was the only node + this.tail.next = null; + //end.prev = null; //does not matter what it points at, there is nothing pointing at it, right? (for garbage collection) + this.size--; + return end.data; + }//end if else + }//end remove + + /** + * @param index the index of the item to be removed + * @return + */ + @Override + public ItemType remove(int index) { + if(index < 0 || index >= this.size) throw new IndexOutOfBoundsException("Index out of bounds in call to remove(int)."); + if(index == this.size - 1){ + return this.remove(); + }else if(index == 0){ + Node start = this.head; + this.head = this.head.next; + this.head.prev = null; + this.size--; + return start.data; + }else{ + Node current = this.head; + for(int i = 0; i < index; i++){ + current = current.next; + } + current.prev.next = current.next; + current.next.prev = current.prev; + this.size--; + return current.data; + }//end if else + } + + /** + * @param item the item to search for + * @return + */ + @Override + public int indexOf(ItemType item) { + Node current = this.head; + for(int i = 0; i < this.size; i++){ + if(current.data.equals(item))return i; + current = current.next; + } + return -1; + } + + /** + * @param item the item to search for + * @return + */ + @Override + public int lastIndexOf(ItemType item) { + Node current = this.head; + for(int i = this.size - 1; i >= 0; i--){ + if(current.data.equals(item))return i; + current = current.prev; + } + return -1; + } + + /** + * @return + */ + @Override + public ListIterator listIterator() { + return null; + } + + + + //**************** Private Subclass Node ************************************* + private class Node { + public ItemType data; + public Node next; + public Node prev; + + public Node(ItemType d){ + this.data = d; + this.next = null; + this.prev = null; + } + } + + private class myTwoWayIterator implements Iterator { + private Node currentNode; + private int currentPosition; + public myTwoWayIterator(){ + currentNode = head; + currentPosition = 0; + } + + /** + * @return + */ + @Override + public boolean hasNext() { + return currentNode.next != null; + } + + /** + * @return + */ + @Override + public ItemType next() { + ItemType data = currentNode.data; + currentNode = currentNode.next; + currentPosition++; + return data; + } + + } + + private class myListIterator implements ListIterator{ + + private Node currentNode; + private int currentPosition; + private int lastIndex; + + public myListIterator(){ + currentNode = head; + currentPosition = 0; + } + + /** + * @return + */ + @Override + public boolean hasNext() { + return currentNode.next != null; + } + + /** + * @return + */ + @Override + public ItemType next() { + ItemType data = currentNode.data; + currentNode = currentNode.next; + lastIndex = currentPosition; + currentPosition++; + return data; + } + + public boolean hasPrevious(){ + return currentNode.prev != null; + } + + public ItemType previous(){ + currentNode = currentNode.prev; + currentPosition--; + lastIndex = currentPosition; + return currentNode.data; + } + + /** + * @return + */ + @Override + public int nextIndex() { + return currentPosition; + } + + /** + * @return + */ + @Override + public int previousIndex() { + return currentPosition - 1; + } + + /** + * + */ + @Override + public void remove() { + DoublyLinkedList.this.remove(lastIndex); + } + + /** + * @param item the element with which to replace the last element returned by + * {@code next} or {@code previous} + */ + @Override + public void set(ItemType item) { + DoublyLinkedList.this.set(lastIndex, item); + } + + /** + * @param item the element to insert + */ + @Override + public void add(ItemType item) { + DoublyLinkedList.this.add(lastIndex, item); + } + } + +} diff --git a/src/edu/greenriver/sdev333/List.java b/src/edu/greenriver/sdev333/List.java index 792abd2..c57aec2 100644 --- a/src/edu/greenriver/sdev333/List.java +++ b/src/edu/greenriver/sdev333/List.java @@ -106,10 +106,11 @@ public interface List extends Collection { * Shifts any subsequent items to the left. * * @param index the index of the item to be removed + * @return * @throws IndexOutOfBoundsException if the index is out of range - * (index < 0 || index >= size()) + * (index < 0 || index >= size()) */ - void remove(int index); + ItemType remove(int index); /** * Returns the index of the first occurrence of the specified item From fd73e73e1e87f34b6f43b2cd915387ddf6be1aac Mon Sep 17 00:00:00 2001 From: AdamZWinter Date: Mon, 30 Jan 2023 15:04:40 -0800 Subject: [PATCH 10/11] All methods written, still need tests --- src/Main.java | 43 ++-- .../greenriver/sdev333/DoublyLinkedList.java | 89 ++++++-- .../sdev333/DoublyLinkedListTest.java | 196 ++++++++++++++++++ 3 files changed, 296 insertions(+), 32 deletions(-) create mode 100644 tests/edu/greenriver/sdev333/DoublyLinkedListTest.java diff --git a/src/Main.java b/src/Main.java index 6fa4692..4a721f4 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,4 +1,5 @@ import edu.greenriver.sdev333.ArrayList; +import edu.greenriver.sdev333.DoublyLinkedList; import edu.greenriver.sdev333.List; import java.util.Iterator; @@ -9,34 +10,42 @@ public static void main(String[] args) { System.out.println("Hello world!"); List friends = new ArrayList(); - System.out.println("Initial size is: "+friends.size()); - System.out.println("List is empty: " + friends.isEmpty()); - - friends.add("Ehren"); - System.out.println("Size after added one: "+friends.size()); +// System.out.println("Initial size is: "+friends.size()); +// System.out.println("List is empty: " + friends.isEmpty()); +// +// friends.add("Ehren"); +// System.out.println("Size after added one: "+friends.size()); for(int i = 0; i < 50; i++){ friends.add("Friend"+i); } - System.out.println("Size after many added: "+friends.size()); +// System.out.println("Size after many added: "+friends.size()); - System.out.println(friends.contains("Friend1")); - System.out.println(friends.contains("Friendx")); +// System.out.println(friends.contains("Friend1")); +// System.out.println(friends.contains("Friendx")); System.out.println(friends); - System.out.print(System.lineSeparator()); - Iterator itr = friends.iterator(); - while(itr.hasNext()){ - String name = itr.next(); - System.out.print(name+" "); - } +// System.out.print(System.lineSeparator()); +// Iterator itr = friends.iterator(); +// while(itr.hasNext()){ +// String name = itr.next(); +// System.out.print(name+" "); +// } +// +// System.out.print(System.lineSeparator()); +// for(String name : friends){ +// System.out.print(name+ " "); +// } + + List friendsLL = new DoublyLinkedList<>(); - System.out.print(System.lineSeparator()); - for(String name : friends){ - System.out.print(name+ " "); + for(int i = 0; i < 50; i++){ + friendsLL.add("Friend"+i); } + System.out.println(friendsLL); + } } \ No newline at end of file diff --git a/src/edu/greenriver/sdev333/DoublyLinkedList.java b/src/edu/greenriver/sdev333/DoublyLinkedList.java index 04afb41..46316a2 100644 --- a/src/edu/greenriver/sdev333/DoublyLinkedList.java +++ b/src/edu/greenriver/sdev333/DoublyLinkedList.java @@ -3,6 +3,8 @@ import javax.swing.text.html.HTMLDocument; import java.util.Iterator; import java.util.ListIterator; +import java.util.NoSuchElementException; +import java.util.Objects; public class DoublyLinkedList implements List { @@ -19,6 +21,31 @@ public DoublyLinkedList(){ this.size = 0; } + /** returns hashcode for this object by hashing toString with Objects.hash + * + * @return int hashcode + */ + @Override + public int hashCode(){ + return Objects.hash(this.toString()); + } + + @Override + public boolean equals(Object other){ + return (other instanceof DoublyLinkedList) && ((DoublyLinkedList) other).hashCode() == hashCode(); + } + + @Override + public String toString(){ + String output = "["; + Iterator itr = this.iterator(); + for(int i=0; i < size-1; i++){ + output = output + itr.next().toString() +", "; + } + output = output + itr.next().toString() +"]"; + return output; + } + /** * @return */ @@ -50,7 +77,7 @@ public boolean contains(ItemType item) { */ @Override public Iterator iterator() { - return new myTwoWayIterator(); + return new myIterator(); } /** @@ -273,7 +300,7 @@ public int indexOf(ItemType item) { */ @Override public int lastIndexOf(ItemType item) { - Node current = this.head; + Node current = this.tail; for(int i = this.size - 1; i >= 0; i--){ if(current.data.equals(item))return i; current = current.prev; @@ -286,7 +313,7 @@ public int lastIndexOf(ItemType item) { */ @Override public ListIterator listIterator() { - return null; + return new myListIterator(); } @@ -304,10 +331,10 @@ public Node(ItemType d){ } } - private class myTwoWayIterator implements Iterator { + private class myIterator implements Iterator { private Node currentNode; private int currentPosition; - public myTwoWayIterator(){ + public myIterator(){ currentNode = head; currentPosition = 0; } @@ -317,7 +344,7 @@ public myTwoWayIterator(){ */ @Override public boolean hasNext() { - return currentNode.next != null; + return currentNode != null; } /** @@ -349,7 +376,7 @@ public myListIterator(){ */ @Override public boolean hasNext() { - return currentNode.next != null; + return currentNode != null; } /** @@ -357,6 +384,7 @@ public boolean hasNext() { */ @Override public ItemType next() { + if(!hasNext()){throw new NoSuchElementException("You should check hasNext() before calling next()");} ItemType data = currentNode.data; currentNode = currentNode.next; lastIndex = currentPosition; @@ -365,17 +393,27 @@ public ItemType next() { } public boolean hasPrevious(){ - return currentNode.prev != null; + return currentPosition != 0; } public ItemType previous(){ - currentNode = currentNode.prev; - currentPosition--; - lastIndex = currentPosition; - return currentNode.data; + if(!hasPrevious()){ + throw new NoSuchElementException("Node at beginning of list has no previous. Check hasPrevious() before calling previous()"); + } + if(currentPosition == size){ + currentNode = tail; + currentPosition--; + lastIndex = currentPosition; + return currentNode.data; + } else{ + currentNode = currentNode.prev; + currentPosition--; + lastIndex = currentPosition; + return currentNode.data; + } } - /** + /** The index-position of the element that you will get when you call next() * @return */ @Override @@ -396,7 +434,18 @@ public int previousIndex() { */ @Override public void remove() { - DoublyLinkedList.this.remove(lastIndex); + if(lastIndex == currentPosition) { + int remove = lastIndex; + ItemType ignoreThis = previous(); + DoublyLinkedList.this.remove(remove); + }else if(lastIndex == size - 1){ + int remove = lastIndex; + ItemType ignoreThis = previous(); + //ItemType ignoreThisToo = previous(); + DoublyLinkedList.this.remove(remove); + }else{ + DoublyLinkedList.this.remove(lastIndex); + } } /** @@ -413,7 +462,17 @@ public void set(ItemType item) { */ @Override public void add(ItemType item) { - DoublyLinkedList.this.add(lastIndex, item); + if(lastIndex == size - 1) { + DoublyLinkedList.this.add(item); + currentNode = tail.next; + currentPosition = size; + }else if(size == 0){ + DoublyLinkedList.this.add(item); + currentNode = head; + currentPosition = 0; + }else{ + DoublyLinkedList.this.add(lastIndex, item); + } } } diff --git a/tests/edu/greenriver/sdev333/DoublyLinkedListTest.java b/tests/edu/greenriver/sdev333/DoublyLinkedListTest.java new file mode 100644 index 0000000..8973448 --- /dev/null +++ b/tests/edu/greenriver/sdev333/DoublyLinkedListTest.java @@ -0,0 +1,196 @@ +package edu.greenriver.sdev333; + +import org.junit.jupiter.api.Test; + +import java.util.Iterator; +import java.util.ListIterator; + +import static org.junit.jupiter.api.Assertions.*; + +class DoublyLinkedListTest { + + DoublyLinkedList testListOne = new DoublyLinkedList<>(); + DoublyLinkedList testListTwo = new DoublyLinkedList<>(); + + @org.junit.jupiter.api.Test + void testEquals() { + testListOne.add("foo"); + testListTwo.add("foo"); + assertEquals(true, testListOne.equals(testListTwo)); + testListOne.add("bar"); + assertEquals(false, testListOne.equals(testListTwo)); + } + + @org.junit.jupiter.api.Test + void size() { + testListOne.add("bar"); + testListOne.add("foo"); + assertEquals(2, testListOne.size()); + } + + @org.junit.jupiter.api.Test + void isEmpty() { + assertEquals(true, testListOne.isEmpty()); + testListOne.add("one"); + assertEquals(false, testListOne.isEmpty()); + } + + @org.junit.jupiter.api.Test + void contains() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + assertEquals(true, testListOne.contains("foo")); + assertEquals(false, testListOne.contains("nope")); + } + + @org.junit.jupiter.api.Test + void iterator() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + Iterator itr = testListOne.iterator(); + assertEquals(true, itr instanceof Iterator); + assertEquals("one", itr.next()); + assertEquals(true, itr.hasNext()); + assertEquals("bar", itr.next()); + assertEquals(true, itr.hasNext()); + assertEquals("foo", itr.next()); + //assertEquals(false, itr.hasNext()); + } + + @org.junit.jupiter.api.Test + void add() { + //trivial : included with other tests + } + + @org.junit.jupiter.api.Test + void remove() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + testListOne.remove(1); + assertEquals("foo", testListOne.get(1)); + } + + @org.junit.jupiter.api.Test + void testToString() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + assertEquals("[one, bar, foo]", testListOne.toString()); + } + + @org.junit.jupiter.api.Test + void clear() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + testListOne.clear(); + assertEquals(true, testListOne.isEmpty()); + assertEquals(0, testListOne.size()); + } + + @org.junit.jupiter.api.Test + void addAll() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + + testListTwo.add("more"); + testListTwo.add("stuff"); + + testListOne.addAll(testListTwo); + assertEquals("[one, bar, foo, more, stuff]", testListOne.toString()); + } + + @org.junit.jupiter.api.Test + void get() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + assertEquals("foo", testListOne.get(2)); + } + + @org.junit.jupiter.api.Test + void set() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + assertEquals("foo", testListOne.get(2)); + testListOne.set(2, "new"); + assertEquals("new", testListOne.get(2)); + } + + @org.junit.jupiter.api.Test + void indexOf() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + testListOne.add("new"); + assertEquals(3, testListOne.indexOf("new")); + } + + @org.junit.jupiter.api.Test + void lastIndexOf() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + testListOne.add("new"); + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + testListOne.add("new"); + assertEquals(2, testListOne.indexOf("foo")); + assertEquals(6, testListOne.lastIndexOf("foo")); + } + + @org.junit.jupiter.api.Test + void listIterator() { + testListOne.add("one"); + testListOne.add("bar"); + testListOne.add("foo"); + testListOne.add("more"); + testListOne.add("stuff"); + + ListIterator itr = testListOne.listIterator(); + assertEquals(0, itr.nextIndex()); + assertEquals("one", itr.next()); + assertEquals("bar", itr.next()); + assertEquals(2, itr.nextIndex()); + assertEquals(true, itr.hasNext()); + assertEquals("foo", itr.next()); + assertEquals(3, itr.nextIndex()); + assertEquals(2, itr.previousIndex()); + assertEquals("foo", itr.previous()); + assertEquals(2, itr.nextIndex()); + assertEquals("foo", itr.next()); + assertEquals("foo", itr.previous()); + assertEquals("bar", itr.previous()); + assertEquals(true, itr.hasPrevious()); + assertEquals("one", itr.previous()); + assertEquals(false, itr.hasPrevious()); + assertEquals("one", itr.next()); + assertEquals(true, itr.hasNext()); + assertEquals("bar", itr.next()); + assertEquals("foo", itr.next()); + assertEquals("more", itr.next()); + assertEquals("stuff", itr.next()); + assertEquals(false, itr.hasNext()); + assertEquals("stuff", itr.previous()); + assertEquals(4, itr.nextIndex()); + assertEquals(3, itr.previousIndex()); + assertEquals("stuff", itr.next()); + itr.remove(); + assertEquals("more", itr.previous()); + itr.set("less"); + assertEquals("less", itr.next()); + assertEquals(false, itr.hasNext()); + itr.add("time"); + assertEquals(false, itr.hasNext()); + assertEquals("time", itr.previous()); + assertEquals("less", itr.previous()); + + + } +} \ No newline at end of file From 4e9b8352b36d04700e356152fb22ac3202b3066c Mon Sep 17 00:00:00 2001 From: AdamZWinter Date: Mon, 30 Jan 2023 15:08:22 -0800 Subject: [PATCH 11/11] DoublylinkedList done with tests passing. --- tests/edu/greenriver/sdev333/DoublyLinkedListTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/edu/greenriver/sdev333/DoublyLinkedListTest.java b/tests/edu/greenriver/sdev333/DoublyLinkedListTest.java index 8973448..ca2c91c 100644 --- a/tests/edu/greenriver/sdev333/DoublyLinkedListTest.java +++ b/tests/edu/greenriver/sdev333/DoublyLinkedListTest.java @@ -1,4 +1,5 @@ package edu.greenriver.sdev333; +//tests passing import org.junit.jupiter.api.Test;