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/.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/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/Main.java b/src/Main.java index 3e59c38..4a721f4 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,5 +1,51 @@ +import edu.greenriver.sdev333.ArrayList; +import edu.greenriver.sdev333.DoublyLinkedList; +import edu.greenriver.sdev333.List; + +import java.util.Iterator; + 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()); +// 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(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()); +// for(String name : friends){ +// System.out.print(name+ " "); +// } + + List friendsLL = new DoublyLinkedList<>(); + + 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/ArrayList.java b/src/edu/greenriver/sdev333/ArrayList.java new file mode 100644 index 0000000..97c700d --- /dev/null +++ b/src/edu/greenriver/sdev333/ArrayList.java @@ -0,0 +1,586 @@ +package edu.greenriver.sdev333; + +import java.util.*; + +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; + + //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 + */ + @Override + 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. + * + * @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 size == 0; + } + + /** + * 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) { + int index = indexOf(item); + return isValidIndex(index); + } + + /** + * Returns an iterator over the elements in this collection. + * + * @return an Iterator over the elements in this collection + */ + @Override + public Iterator iterator() { + return new MyCustomIterator(); + } + + + /** + * 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(!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. + * + * @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) { + 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; + } + + /** + * 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() { + this.data = (ItemType[]) new Object[10]; + this.size = 0; + } + + /** + * 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) { + //fail fast (fail loud) + //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; + } + + /** + * 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) { + //fail fast (fail loud) + //throw new UnsupportedOperationException("addAll method is not supported in this implementation"); + for(ItemType other : otherCollection){ + add(other); + } + } + + /** + * 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) { + //fail fast (fail loud) + throw new UnsupportedOperationException("addAll method is not supported in this implementation"); + } + + /** + * 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) { + //fail fast (fail loud) + throw new UnsupportedOperationException("addAll method is not supported in this implementation"); + } + + /** + * 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) { + if(!isValidIndex(index)){ + throw new IndexOutOfBoundsException("index is out of bounds"); + } + return data[index]; + } + + /** + * 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) { + if(!isValidIndex(index)){ + throw new IndexOutOfBoundsException("index is out of bounds"); + } + data[index] = 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) { + 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; + } + + /** + * 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 + * @return + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index >= size()) + */ + @Override + 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= 0; i--){ + if(item.equals(data[i])){ + return i; + } + } + return -1; + } + + /** + * 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 new MyCustomListIterator(); + } + + 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; + private int lastIndex; + public MyCustomListIterator(){ + currentPosition = 0; + lastIndex = -1; + } + + /** + * 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 currentPosition < size(); + } + + /** + * 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() { + lastIndex = currentPosition; + return get(currentPosition++); + } + + /** + * 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() { + 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; + } + + /** + * 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 currentPosition; + } + + /** + * 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 currentPosition - 1; + } + + /** + * 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() { + 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/src/edu/greenriver/sdev333/DoublyLinkedList.java b/src/edu/greenriver/sdev333/DoublyLinkedList.java new file mode 100644 index 0000000..46316a2 --- /dev/null +++ b/src/edu/greenriver/sdev333/DoublyLinkedList.java @@ -0,0 +1,479 @@ +package edu.greenriver.sdev333; + +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 { + + + 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; + } + + /** 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 + */ + @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 myIterator(); + } + + /** + * @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.tail; + 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 new myListIterator(); + } + + + + //**************** 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 myIterator implements Iterator { + private Node currentNode; + private int currentPosition; + public myIterator(){ + currentNode = head; + currentPosition = 0; + } + + /** + * @return + */ + @Override + public boolean hasNext() { + return currentNode != 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 != null; + } + + /** + * @return + */ + @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; + currentPosition++; + return data; + } + + public boolean hasPrevious(){ + return currentPosition != 0; + } + + public ItemType previous(){ + 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 + public int nextIndex() { + return currentPosition; + } + + /** + * @return + */ + @Override + public int previousIndex() { + return currentPosition - 1; + } + + /** + * + */ + @Override + public void remove() { + 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); + } + } + + /** + * @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) { + 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/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 diff --git a/tests/edu/greenriver/sdev333/ArrayListTest.java b/tests/edu/greenriver/sdev333/ArrayListTest.java new file mode 100644 index 0000000..28d9d60 --- /dev/null +++ b/tests/edu/greenriver/sdev333/ArrayListTest.java @@ -0,0 +1,205 @@ +package edu.greenriver.sdev333; + +import java.util.Iterator; +import java.util.ListIterator; + +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() { + 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 diff --git a/tests/edu/greenriver/sdev333/DoublyLinkedListTest.java b/tests/edu/greenriver/sdev333/DoublyLinkedListTest.java new file mode 100644 index 0000000..ca2c91c --- /dev/null +++ b/tests/edu/greenriver/sdev333/DoublyLinkedListTest.java @@ -0,0 +1,197 @@ +package edu.greenriver.sdev333; +//tests passing + +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