From e15cf933aa52e622fb13a88025a2e343bf6db484 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Mar 2023 00:25:23 -0700 Subject: [PATCH] don't need tree list --- .../github/btrekkie/tree_list/TreeList.java | 461 --------------- .../btrekkie/tree_list/TreeListNode.java | 40 -- .../btrekkie/tree_list/test/TreeListTest.java | 556 ------------------ 3 files changed, 1057 deletions(-) delete mode 100644 src/main/java/com/github/btrekkie/tree_list/TreeList.java delete mode 100644 src/main/java/com/github/btrekkie/tree_list/TreeListNode.java delete mode 100644 src/test/java/com/github/btrekkie/tree_list/test/TreeListTest.java diff --git a/src/main/java/com/github/btrekkie/tree_list/TreeList.java b/src/main/java/com/github/btrekkie/tree_list/TreeList.java deleted file mode 100644 index 3201bbd23..000000000 --- a/src/main/java/com/github/btrekkie/tree_list/TreeList.java +++ /dev/null @@ -1,461 +0,0 @@ -package com.github.btrekkie.tree_list; -import java.util.AbstractList; -import java.util.ArrayList; -import java.util.Collection; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.NoSuchElementException; - -import com.github.btrekkie.red_black_node.RedBlackNode; - -/** - * Implements a list using a self-balancing binary search tree augmented by subtree size. The benefit of this compared - * to ArrayList or LinkedList is that it supports both decent random access and quickly adding to or removing from the - * middle of the list. Operations have the following running times: - * - * size(): O(1) - * get, set, add, remove: O(log N) - * addAll: O(log N + P), where P is the number of elements we add - * iterator(): O(log N + P + M log N), where P is the number of elements over which we iterate and M is the number of - * elements we remove - * listIterator: O(log N + P + M log N + R log N), where P is the number of times we iterate over or set an element, M - * is the number of elements we add or remove, and R is the number of times we change the direction of iteration - * clear(): O(1), excluding garbage collection - * subList.clear(): O(log N), excluding garbage collection - * Constructor: O(N) - * - * This class is similar to an Apache Commons Collections class by the same name. I speculate that the Apache class is - * faster than this (by a constant factor) for most operations. However, this class's implementations of addAll and - * subList.clear() are asymptotically faster than the Apache class's implementations. - */ -public class TreeList extends AbstractList { - /** The dummy leaf node. */ - private final TreeListNode leaf = new TreeListNode(null); - - /** The root node of the tree. */ - private TreeListNode root; - - /** Constructs a new empty TreeList. */ - public TreeList() { - root = leaf; - } - - /** Constructs a new TreeList containing the specified values, in iteration order. */ - public TreeList(Collection values) { - root = createTree(values); - } - - /** Returns the root of a perfectly height-balanced tree containing the specified values, in iteration order. */ - private TreeListNode createTree(Collection values) { - List> nodes = new ArrayList>(values.size()); - for (T value : values) { - nodes.add(new TreeListNode(value)); - } - return RedBlackNode.>createTree(nodes, leaf); - } - - /** - * Returns the node for get(index). Throws an IndexOutOfBoundsException if "index" is not in the range [0, size()). - */ - private TreeListNode getNode(int index) { - if (index < 0 || index >= root.size) { - throw new IndexOutOfBoundsException("Index " + index + " is not in the range [0, " + root.size + ")"); - } - int rank = index; - TreeListNode node = root; - while (rank != node.left.size) { - if (rank < node.left.size) { - node = node.left; - } else { - rank -= node.left.size + 1; - node = node.right; - } - } - return node; - } - - @Override - public T get(int index) { - return getNode(index).value; - } - - @Override - public int size() { - return root.size; - } - - @Override - public boolean isEmpty() { - return root == leaf; - } - - @Override - public T set(int index, T value) { - modCount++; - TreeListNode node = getNode(index); - T oldValue = node.value; - node.value = value; - return oldValue; - } - - @Override - public void add(int index, T value) { - if (index < 0 || index > root.size) { - throw new IndexOutOfBoundsException("Index " + index + " is not in the range [0, " + root.size + "]"); - } - modCount++; - - TreeListNode newNode = new TreeListNode(value); - newNode.left = leaf; - newNode.right = leaf; - if (root.isLeaf()) { - root = newNode; - newNode.isRed = false; - return; - } - newNode.isRed = true; - if (index < root.size) { - TreeListNode node = getNode(index); - if (node.left.isLeaf()) { - node.left = newNode; - newNode.parent = node; - } else { - node = node.predecessor(); - node.right = newNode; - newNode.parent = node; - } - } else { - TreeListNode node; - node = root.max(); - node.right = newNode; - newNode.parent = node; - } - - root = newNode.fixInsertion(); - } - - @Override - public T remove(int index) { - TreeListNode node = getNode(index); - modCount++; - root = node.remove(); - return node.value; - } - - @Override - public boolean addAll(int index, Collection values) { - if (index < 0 || index > root.size) { - throw new IndexOutOfBoundsException("Index " + index + " is not in the range [0, " + root.size + "]"); - } - modCount++; - - if (values.isEmpty()) { - return false; - } else { - if (index >= root.size) { - root = root.concatenate(createTree(values)); - } else { - TreeListNode[] split = root.split(getNode(index)); - root = split[0].concatenate(createTree(values)).concatenate(split[1]); - } - return true; - } - } - - @Override - public boolean addAll(Collection values) { - modCount++; - if (values.isEmpty()) { - return false; - } else { - root = root.concatenate(createTree(values)); - return true; - } - } - - @Override - protected void removeRange(int startIndex, int endIndex) { - if (startIndex != endIndex) { - modCount++; - TreeListNode last; - if (endIndex == root.size) { - last = leaf; - } else { - TreeListNode[] split = root.split(getNode(endIndex)); - root = split[0]; - last = split[1]; - } - TreeListNode first = root.split(getNode(startIndex))[0]; - root = first.concatenate(last); - } - } - - @Override - public void clear() { - modCount++; - root = leaf; - } - - /** The class for TreeList.iterator(). */ - private class TreeListIterator implements Iterator { - /** The value of TreeList.this.modCount we require to continue iteration without concurrent modification. */ - private int modCount = TreeList.this.modCount; - - /** - * The node containing the last element next() returned. This is null if we have yet to call next() or we have - * called remove() since the last call to next(). - */ - private TreeListNode node; - - /** The node containing next(). This is null if we have reached the end of the list. */ - private TreeListNode nextNode; - - /** Whether we have (successfully) called next(). */ - private boolean haveCalledNext; - - private TreeListIterator() { - if (root.isLeaf()) { - nextNode = null; - } else { - nextNode = root.min(); - } - } - - @Override - public boolean hasNext() { - return nextNode != null; - } - - @Override - public T next() { - if (nextNode == null) { - throw new NoSuchElementException("Reached the end of the list"); - } else if (TreeList.this.modCount != modCount) { - throw new ConcurrentModificationException(); - } - haveCalledNext = true; - node = nextNode; - nextNode = nextNode.successor(); - return node.value; - } - - @Override - public void remove() { - if (node == null) { - if (!haveCalledNext) { - throw new IllegalStateException("Must call next() before calling remove()"); - } else { - throw new IllegalStateException("Already removed this element"); - } - } else if (TreeList.this.modCount != modCount) { - throw new ConcurrentModificationException(); - } - root = node.remove(); - node = null; - TreeList.this.modCount++; - modCount = TreeList.this.modCount; - } - } - - @Override - public Iterator iterator() { - return new TreeListIterator(); - } - - /** The class for TreeList.listIterator. */ - private class TreeListListIterator implements ListIterator { - /** The value of TreeList.this.modCount we require to continue iteration without concurrent modification. */ - private int modCount = TreeList.this.modCount; - - /** The current return value for nextIndex(). */ - private int nextIndex; - - /** The node for next(), or null if hasNext() is false. */ - private TreeListNode nextNode; - - /** The node for previous(), or null if hasPrevious() is false. */ - private TreeListNode prevNode; - - /** Whether we have called next() or previous(). */ - private boolean haveCalledNextOrPrevious; - - /** Whether we (successfully) called next() more recently than previous(). */ - private boolean justCalledNext; - - /** - * Whether we have (successfully) called remove() or "add" since the last (successful) call to next() or - * previous(). - */ - private boolean haveModified; - - /** - * Constructs a new TreeListListIterator. - * @param index The starting index, as in the "index" argument to listIterator. This method assumes that - * 0 <= index < root.size. - */ - private TreeListListIterator(int index) { - nextIndex = index; - if (index > 0) { - prevNode = getNode(index - 1); - nextNode = prevNode.successor(); - } else { - prevNode = null; - if (root.size > 0) { - nextNode = root.min(); - } else { - nextNode = null; - } - } - } - - @Override - public boolean hasNext() { - if (modCount != TreeList.this.modCount) { - throw new ConcurrentModificationException(); - } - return nextNode != null; - } - - @Override - public T next() { - if (nextNode == null) { - throw new NoSuchElementException("Reached the end of the list"); - } else if (modCount != TreeList.this.modCount) { - throw new ConcurrentModificationException(); - } - - haveCalledNextOrPrevious = true; - justCalledNext = true; - haveModified = false; - nextIndex++; - prevNode = nextNode; - nextNode = nextNode.successor(); - return prevNode.value; - } - - @Override - public int nextIndex() { - if (modCount != TreeList.this.modCount) { - throw new ConcurrentModificationException(); - } - return nextIndex; - } - - @Override - public boolean hasPrevious() { - if (modCount != TreeList.this.modCount) { - throw new ConcurrentModificationException(); - } - return prevNode != null; - } - - @Override - public T previous() { - if (prevNode == null) { - throw new NoSuchElementException("Reached the beginning of the list"); - } else if (modCount != TreeList.this.modCount) { - throw new ConcurrentModificationException(); - } - - haveCalledNextOrPrevious = true; - justCalledNext = false; - haveModified = false; - nextIndex--; - nextNode = prevNode; - prevNode = prevNode.predecessor(); - return nextNode.value; - } - - @Override - public int previousIndex() { - return nextIndex - 1; - } - - @Override - public void set(T value) { - if (!haveCalledNextOrPrevious) { - throw new IllegalStateException("Must call next() or previous() before calling \"set\""); - } else if (haveModified) { - throw new IllegalStateException("Already modified the list at this position"); - } else if (modCount != TreeList.this.modCount) { - throw new ConcurrentModificationException(); - } - - if (justCalledNext) { - prevNode.value = value; - } else { - nextNode.value = value; - } - TreeList.this.modCount++; - modCount = TreeList.this.modCount; - } - - @Override - public void add(T value) { - if (haveModified) { - throw new IllegalStateException("Already modified the list at this position"); - } else if (modCount != TreeList.this.modCount) { - throw new ConcurrentModificationException(); - } - - // Create the new node - TreeListNode newNode = new TreeListNode(value); - newNode.left = leaf; - newNode.right = leaf; - newNode.isRed = true; - - // Insert newNode. There is guaranteed to be a leaf child of prevNode or nextNode where we can insert it. - if (nextNode != null && nextNode.left.isLeaf()) { - nextNode.left = newNode; - newNode.parent = nextNode; - } else if (prevNode != null) { - prevNode.right = newNode; - newNode.parent = prevNode; - } else { - root = newNode; - } - - prevNode = newNode; - root = newNode.fixInsertion(); - nextIndex++; - haveModified = true; - TreeList.this.modCount++; - modCount = TreeList.this.modCount; - } - - @Override - public void remove() { - if (!haveCalledNextOrPrevious) { - throw new IllegalStateException("Must call next() or previous() before calling remove()"); - } else if (haveModified) { - throw new IllegalStateException("Already modified the list at this position"); - } else if (modCount != TreeList.this.modCount) { - throw new ConcurrentModificationException(); - } - - if (justCalledNext) { - TreeListNode predecessor = prevNode.predecessor(); - root = prevNode.remove(); - prevNode = predecessor; - } else { - TreeListNode successor = nextNode.successor(); - root = nextNode.remove(); - nextNode = successor; - } - - haveModified = true; - TreeList.this.modCount++; - modCount = TreeList.this.modCount; - } - } - - @Override - public ListIterator listIterator(int index) { - if (index < 0 || index > root.size) { - throw new IndexOutOfBoundsException("Index " + index + " is not in the range [0, " + root.size + "]"); - } - return new TreeListListIterator(index); - } -} diff --git a/src/main/java/com/github/btrekkie/tree_list/TreeListNode.java b/src/main/java/com/github/btrekkie/tree_list/TreeListNode.java deleted file mode 100644 index de78368db..000000000 --- a/src/main/java/com/github/btrekkie/tree_list/TreeListNode.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.github.btrekkie.tree_list; - -import com.github.btrekkie.red_black_node.RedBlackNode; - -/** A node in a TreeList. See the comments for TreeList. */ -class TreeListNode extends RedBlackNode> { - /** The element stored in the node. The value is unspecified if this is a leaf node. */ - public T value; - - /** The number of elements in the subtree rooted at this node. */ - public int size; - - public TreeListNode(T value) { - this.value = value; - } - - @Override - public boolean augment() { - int newSize = left.size + right.size + 1; - if (newSize == size) { - return false; - } else { - size = newSize; - return true; - } - } - - @Override - public void assertNodeIsValid() { - int expectedSize; - if (isLeaf()) { - expectedSize = 0; - } else { - expectedSize = left.size + right.size + 1; - } - if (size != expectedSize) { - throw new RuntimeException("The node's size does not match that of the children"); - } - } -} diff --git a/src/test/java/com/github/btrekkie/tree_list/test/TreeListTest.java b/src/test/java/com/github/btrekkie/tree_list/test/TreeListTest.java deleted file mode 100644 index e01a63810..000000000 --- a/src/test/java/com/github/btrekkie/tree_list/test/TreeListTest.java +++ /dev/null @@ -1,556 +0,0 @@ -package com.github.btrekkie.tree_list.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.NoSuchElementException; - -import org.junit.Test; - -import com.github.btrekkie.tree_list.TreeList; - -public class TreeListTest { - /** Tests TreeList.add. */ - @Test - public void testAdd() { - List list = new TreeList(); - assertEquals(Collections.emptyList(), list); - assertEquals(0, list.size()); - assertTrue(list.isEmpty()); - - list.add(4); - list.add(17); - list.add(-4); - list.add(null); - assertEquals(Arrays.asList(4, 17, -4, null), list); - assertEquals(4, list.size()); - assertFalse(list.isEmpty()); - assertEquals(-4, list.get(2).intValue()); - - boolean threwException; - try { - list.get(-3); - threwException = false; - } catch (IndexOutOfBoundsException exception) { - threwException = true; - } - assertTrue(threwException); - try { - list.get(9); - threwException = false; - } catch (IndexOutOfBoundsException exception) { - threwException = true; - } - assertTrue(threwException); - try { - list.add(-3, 5); - threwException = false; - } catch (IndexOutOfBoundsException exception) { - threwException = true; - } - assertTrue(threwException); - try { - list.add(9, 10); - threwException = false; - } catch (IndexOutOfBoundsException exception) { - threwException = true; - } - assertTrue(threwException); - - list.add(1, 6); - list.add(0, -1); - list.add(6, 42); - assertEquals(Arrays.asList(-1, 4, 6, 17, -4, null, 42), list); - assertEquals(7, list.size()); - assertEquals(6, list.get(2).intValue()); - assertEquals(null, list.get(5)); - - list = new TreeList(); - for (int i = 0; i < 200; i++) { - list.add(i + 300); - } - for (int i = 0; i < 300; i++) { - list.add(i, i); - } - for (int i = 499; i >= 0; i--) { - list.add(500, i + 500); - } - List expected = new ArrayList(1000); - for (int i = 0; i < 1000; i++) { - expected.add(i); - } - assertEquals(expected, list); - assertEquals(1000, list.size()); - assertFalse(list.isEmpty()); - assertEquals(777, list.get(777).intValue()); - assertEquals(123, list.get(123).intValue()); - assertEquals(0, list.get(0).intValue()); - assertEquals(999, list.get(999).intValue()); - } - - /** Tests TreeList.remove. */ - @Test - public void testRemove() { - List list = new TreeList(); - list.add(17); - list.add(-5); - list.add(null); - list.add(0); - list.add(1, 16); - assertEquals(null, list.remove(3)); - assertEquals(17, list.remove(0).intValue()); - assertEquals(0, list.remove(2).intValue()); - assertEquals(Arrays.asList(16, -5), list); - assertEquals(2, list.size()); - assertFalse(list.isEmpty()); - assertEquals(16, list.get(0).intValue()); - assertEquals(-5, list.get(1).intValue()); - - boolean threwException; - try { - list.remove(-3); - threwException = false; - } catch (IndexOutOfBoundsException exception) { - threwException = true; - } - assertTrue(threwException); - try { - list.remove(9); - threwException = false; - } catch (IndexOutOfBoundsException exception) { - threwException = true; - } - assertTrue(threwException); - - list = new TreeList(); - for (int i = 0; i < 1000; i++) { - list.add(i); - } - for (int i = 0; i < 250; i++) { - assertEquals(2 * i + 501, list.remove(501).intValue()); - assertEquals(2 * i + 1, list.remove(i + 1).intValue()); - } - List expected = new ArrayList(500); - for (int i = 0; i < 500; i++) { - expected.add(2 * i); - } - assertEquals(expected, list); - assertEquals(500, list.size()); - assertFalse(list.isEmpty()); - assertEquals(0, list.get(0).intValue()); - assertEquals(998, list.get(499).intValue()); - assertEquals(84, list.get(42).intValue()); - assertEquals(602, list.get(301).intValue()); - } - - /** Tests TreeList.set.*/ - @Test - public void testSet() { - List list = new TreeList(); - list.addAll(Arrays.asList(5, 17, 42, -6, null, 3, null)); - list.set(3, 12); - list.set(0, 6); - list.set(6, 88); - boolean threwException; - try { - list.set(7, 2); - threwException = false; - } catch (IndexOutOfBoundsException exception) { - threwException = true; - } - assertTrue(threwException); - try { - list.set(-1, 4); - threwException = false; - } catch (IndexOutOfBoundsException exception) { - threwException = true; - } - assertTrue(threwException); - assertEquals(Arrays.asList(6, 17, 42, 12, null, 3, 88), list); - assertEquals(7, list.size()); - assertFalse(list.isEmpty()); - assertEquals(42, list.get(2).intValue()); - assertEquals(6, list.get(0).intValue()); - assertEquals(88, list.get(6).intValue()); - - list = new TreeList(); - for (int i = 0; i < 1000; i++) { - list.add(999 - i); - } - for (int i = 0; i < 500; i++) { - list.set(i, i); - list.set(i + 500, i + 500); - } - List expected = new ArrayList(1000); - for (int i = 0; i < 1000; i++) { - expected.add(i); - } - assertEquals(expected, list); - assertEquals(1000, list.size()); - assertFalse(list.isEmpty()); - assertEquals(123, list.get(123).intValue()); - assertEquals(777, list.get(777).intValue()); - assertEquals(0, list.get(0).intValue()); - assertEquals(999, list.get(999).intValue()); - } - - /** Tests TreeList.addAll. */ - @Test - public void testAddAll() { - List list = new TreeList(); - list.add(3); - list.add(42); - list.add(16); - list.addAll(0, Arrays.asList(15, 4, -1)); - list.addAll(2, Arrays.asList(6, 14)); - list.addAll(1, Collections.emptyList()); - list.addAll(8, Arrays.asList(null, 7)); - list.addAll(Arrays.asList(-5, 5)); - assertEquals(Arrays.asList(15, 4, 6, 14, -1, 3, 42, 16, null, 7, -5, 5), list); - assertEquals(12, list.size()); - assertFalse(list.isEmpty()); - assertEquals(14, list.get(3).intValue()); - assertEquals(15, list.get(0).intValue()); - assertEquals(5, list.get(11).intValue()); - - list = new TreeList(); - list.add(7); - list.addAll(Collections.singleton(37)); - assertEquals(Arrays.asList(7, 37), list); - - list = new TreeList(); - List list2 = new ArrayList(400); - for (int i = 0; i < 200; i++) { - list2.add(i + 100); - } - for (int i = 0; i < 200; i++) { - list2.add(i + 700); - } - list.addAll(list2); - list2.clear(); - for (int i = 0; i < 100; i++) { - list2.add(i); - } - list.addAll(0, list2); - list2.clear(); - for (int i = 0; i < 400; i++) { - list2.add(i + 300); - } - list.addAll(300, list2); - list2.clear(); - for (int i = 0; i < 100; i++) { - list2.add(i + 900); - } - list.addAll(900, list2); - List expected = new ArrayList(1000); - for (int i = 0; i < 1000; i++) { - expected.add(i); - } - assertEquals(expected, list); - assertEquals(1000, list.size()); - assertFalse(list.isEmpty()); - assertEquals(123, list.get(123).intValue()); - assertEquals(777, list.get(777).intValue()); - assertEquals(0, list.get(0).intValue()); - assertEquals(999, list.get(999).intValue()); - } - - /** Tests TreeList.subList.clear(). */ - @Test - public void testClearSubList() { - List list = new TreeList(); - list.addAll(Arrays.asList(6, 42, -3, 15, 7, 99, 6, 12)); - list.subList(2, 4).clear(); - list.subList(0, 1).clear(); - list.subList(4, 4).clear(); - list.subList(3, 5).clear(); - assertEquals(Arrays.asList(42, 7, 99), list); - assertEquals(3, list.size()); - assertFalse(list.isEmpty()); - assertEquals(42, list.get(0).intValue()); - assertEquals(7, list.get(1).intValue()); - assertEquals(99, list.get(2).intValue()); - - list = new TreeList(); - for (int i = 0; i < 200; i++) { - list.add(-1); - } - for (int i = 0; i < 500; i++) { - list.add(i); - } - for (int i = 0; i < 400; i++) { - list.add(-1); - } - for (int i = 0; i < 500; i++) { - list.add(i + 500); - } - for (int i = 0; i < 600; i++) { - list.add(-1); - } - list.subList(1600, 2200).clear(); - list.subList(777, 777).clear(); - list.subList(700, 1100).clear(); - list.subList(0, 200).clear(); - List expected = new ArrayList(1000); - for (int i = 0; i < 1000; i++) { - expected.add(i); - } - assertEquals(expected, list); - assertEquals(1000, list.size()); - assertFalse(list.isEmpty()); - assertEquals(123, list.get(123).intValue()); - assertEquals(777, list.get(777).intValue()); - assertEquals(0, list.get(0).intValue()); - assertEquals(999, list.get(999).intValue()); - - list = new TreeList(); - list.addAll(Arrays.asList(-3, null, 8, 14, 9, 42)); - list.subList(0, 6).clear(); - assertEquals(Collections.emptyList(), list); - assertEquals(0, list.size()); - assertTrue(list.isEmpty()); - } - - /** Tests TreeList(Collection). */ - @Test - public void testConstructor() { - List list = new TreeList(Arrays.asList(1, 5, 42, -6, null, 3)); - assertEquals(Arrays.asList(1, 5, 42, -6, null, 3), list); - assertEquals(6, list.size()); - assertFalse(list.isEmpty()); - assertEquals(42, list.get(2).intValue()); - assertEquals(1, list.get(0).intValue()); - assertEquals(3, list.get(5).intValue()); - - List expected = new ArrayList(1000); - for (int i = 0; i < 1000; i++) { - expected.add(i); - } - list = new TreeList(expected); - assertEquals(expected, list); - assertEquals(1000, list.size()); - assertFalse(list.isEmpty()); - assertEquals(123, list.get(123).intValue()); - assertEquals(777, list.get(777).intValue()); - assertEquals(0, list.get(0).intValue()); - assertEquals(999, list.get(999).intValue()); - } - - /** Tests TreeList.clear(). */ - @Test - public void testClear() { - List list = new TreeList(); - list.addAll(Arrays.asList(7, 16, 5, 42)); - list.clear(); - assertEquals(Collections.emptyList(), list); - assertEquals(0, list.size()); - assertTrue(list.isEmpty()); - - for (int i = 0; i < 1000; i++) { - list.add(i); - } - list.clear(); - assertEquals(Collections.emptyList(), list); - assertEquals(0, list.size()); - assertTrue(list.isEmpty()); - } - - /** Tests TreeList.iterator(). */ - @Test - public void testIterator() { - List list = new TreeList(); - Iterator iterator = list.iterator(); - assertFalse(iterator.hasNext()); - boolean threwException; - try { - iterator.next(); - threwException = false; - } catch (NoSuchElementException exception) { - threwException = true; - } - assertTrue(threwException); - - list = new TreeList(Arrays.asList(42, 16, null, 7, 8, 3, 12)); - iterator = list.iterator(); - try { - iterator.remove(); - threwException = false; - } catch (IllegalStateException exception) { - threwException = true; - } - assertTrue(threwException); - assertTrue(iterator.hasNext()); - assertEquals(42, iterator.next().intValue()); - assertEquals(16, iterator.next().intValue()); - assertEquals(null, iterator.next()); - assertTrue(iterator.hasNext()); - assertEquals(7, iterator.next().intValue()); - iterator.remove(); - try { - iterator.remove(); - threwException = false; - } catch (IllegalStateException exception) { - threwException = true; - } - assertTrue(threwException); - assertTrue(iterator.hasNext()); - assertTrue(iterator.hasNext()); - assertEquals(8, iterator.next().intValue()); - assertTrue(iterator.hasNext()); - assertEquals(3, iterator.next().intValue()); - assertTrue(iterator.hasNext()); - assertEquals(12, iterator.next().intValue()); - assertFalse(iterator.hasNext()); - iterator.remove(); - assertFalse(iterator.hasNext()); - try { - iterator.next(); - threwException = false; - } catch (NoSuchElementException exception) { - threwException = true; - } - assertTrue(threwException); - assertEquals(Arrays.asList(42, 16, null, 8, 3), list); - - list = new TreeList(); - for (int i = 0; i < 1000; i++) { - list.add(i); - } - iterator = list.iterator(); - for (int i = 0; i < 500; i++) { - assertTrue(iterator.hasNext()); - assertEquals(2 * i, iterator.next().intValue()); - assertTrue(iterator.hasNext()); - assertEquals(2 * i + 1, iterator.next().intValue()); - iterator.remove(); - } - assertFalse(iterator.hasNext()); - List expected = new ArrayList(500); - for (int i = 0; i < 500; i++) { - expected.add(2 * i); - } - assertEquals(expected, list); - } - - /** Tests TreeList.listIterator. */ - @Test - public void testListIterator() { - List list = new TreeList(); - list.addAll(Arrays.asList(7, 16, 42, -3, 12, 25, 8, 9)); - boolean threwException; - try { - list.listIterator(-1); - threwException = false; - } catch (IndexOutOfBoundsException exception) { - threwException = true; - } - assertTrue(threwException); - try { - list.listIterator(18); - threwException = false; - } catch (IndexOutOfBoundsException exception) { - threwException = true; - } - assertTrue(threwException); - ListIterator iterator = list.listIterator(1); - assertTrue(iterator.hasNext()); - assertTrue(iterator.hasPrevious()); - assertEquals(16, iterator.next().intValue()); - iterator.add(6); - try { - iterator.set(-1); - threwException = false; - } catch (IllegalStateException exception) { - threwException = true; - } - assertTrue(threwException); - try { - iterator.add(9); - threwException = false; - } catch (IllegalStateException exception) { - threwException = true; - } - assertTrue(threwException); - try { - iterator.remove(); - threwException = false; - } catch (IllegalStateException exception) { - threwException = true; - } - assertTrue(threwException); - assertEquals(6, iterator.previous().intValue()); - assertEquals(6, iterator.next().intValue()); - assertEquals(2, iterator.previousIndex()); - assertEquals(3, iterator.nextIndex()); - assertEquals(42, iterator.next().intValue()); - assertEquals(-3, iterator.next().intValue()); - assertEquals(12, iterator.next().intValue()); - iterator.remove(); - assertEquals(-3, iterator.previous().intValue()); - iterator.remove(); - assertEquals(25, iterator.next().intValue()); - iterator.set(14); - assertEquals(8, iterator.next().intValue()); - assertEquals(9, iterator.next().intValue()); - assertFalse(iterator.hasNext()); - try { - iterator.next(); - threwException = false; - } catch (NoSuchElementException exception) { - threwException = true; - } - assertTrue(threwException); - assertEquals(9, iterator.previous().intValue()); - iterator.set(10); - assertEquals(Arrays.asList(7, 16, 6, 42, 14, 8, 10), list); - assertEquals(7, list.size()); - assertFalse(list.isEmpty()); - assertEquals(42, list.get(3).intValue()); - assertEquals(7, list.get(0).intValue()); - assertEquals(10, list.get(6).intValue()); - - list = new TreeList(); - for (int i = 0; i < 1000; i++) { - list.add(-1); - } - iterator = list.listIterator(); - for (int i = 0; i < 500; i++) { - iterator.add(i); - iterator.next(); - } - for (int i = 0; i < 500; i++) { - iterator.previous(); - iterator.remove(); - iterator.previous(); - } - iterator = list.listIterator(500); - for (int i = 0; i < 250; i++) { - iterator.next(); - iterator.set(2 * i + 500); - iterator.next(); - } - for (int i = 0; i < 250; i++) { - iterator.previous(); - iterator.set(999 - 2 * i); - iterator.previous(); - } - List expected = new ArrayList(1000); - for (int i = 0; i < 1000; i++) { - expected.add(i); - } - assertEquals(expected, list); - assertEquals(1000, list.size()); - assertFalse(list.isEmpty()); - assertEquals(123, list.get(123).intValue()); - assertEquals(777, list.get(777).intValue()); - assertEquals(0, list.get(0).intValue()); - assertEquals(999, list.get(999).intValue()); - } -}