diff --git a/iterator/etc/bst.jpg b/iterator/etc/bst.jpg new file mode 100644 index 000000000..f7ed6af82 Binary files /dev/null and b/iterator/etc/bst.jpg differ diff --git a/iterator/etc/iterator.ucls b/iterator/etc/iterator.ucls index 440f9a28b..d36dad95d 100644 --- a/iterator/etc/iterator.ucls +++ b/iterator/etc/iterator.ucls @@ -1,7 +1,7 @@ - - - - - diff --git a/iterator/src/main/java/com/iluwatar/iterator/App.java b/iterator/src/main/java/com/iluwatar/iterator/App.java index d283347cb..35b2592e5 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/App.java +++ b/iterator/src/main/java/com/iluwatar/iterator/App.java @@ -1,76 +1,95 @@ /** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä + * The MIT License Copyright (c) 2014-2016 Ilkka Seppälä * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package com.iluwatar.iterator; +import static com.iluwatar.iterator.list.ItemType.ANY; +import static com.iluwatar.iterator.list.ItemType.POTION; +import static com.iluwatar.iterator.list.ItemType.RING; +import static com.iluwatar.iterator.list.ItemType.WEAPON; + +import com.iluwatar.iterator.bst.BstIterator; +import com.iluwatar.iterator.bst.TreeNode; +import com.iluwatar.iterator.list.Item; +import com.iluwatar.iterator.list.ItemType; +import com.iluwatar.iterator.list.TreasureChest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * * The Iterator pattern is a design pattern in which an iterator is used to traverse a container and * access the container's elements. The Iterator pattern decouples algorithms from containers. *

- * In this example the Iterator ({@link ItemIterator}) adds abstraction layer on top of a collection + * In this example the Iterator ({@link Iterator}) adds abstraction layer on top of a collection * ({@link TreasureChest}). This way the collection can change its internal implementation without * affecting its clients. - * */ public class App { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + private static final TreasureChest TREASURE_CHEST = new TreasureChest(); + + private static void demonstrateTreasureChestIteratorForType(ItemType itemType) { + LOGGER.info("------------------------"); + LOGGER.info("Item Iterator for ItemType " + itemType + ": "); + Iterator itemIterator = TREASURE_CHEST.iterator(itemType); + while (itemIterator.hasNext()) { + LOGGER.info(itemIterator.next().toString()); + } + } + + private static void demonstrateBstIterator() { + LOGGER.info("------------------------"); + LOGGER.info("BST Iterator: "); + TreeNode root = buildIntegerBst(); + BstIterator bstIterator = new BstIterator<>(root); + while (bstIterator.hasNext()) { + LOGGER.info("Next node: " + bstIterator.next().getVal()); + } + } + + private static TreeNode buildIntegerBst() { + TreeNode root = new TreeNode<>(8); + + root.insert(3); + root.insert(10); + root.insert(1); + root.insert(6); + root.insert(14); + root.insert(4); + root.insert(7); + root.insert(13); + + return root; + } + /** * Program entry point - * + * * @param args command line args */ public static void main(String[] args) { - TreasureChest chest = new TreasureChest(); + demonstrateTreasureChestIteratorForType(RING); + demonstrateTreasureChestIteratorForType(POTION); + demonstrateTreasureChestIteratorForType(WEAPON); + demonstrateTreasureChestIteratorForType(ANY); - ItemIterator ringIterator = chest.iterator(ItemType.RING); - while (ringIterator.hasNext()) { - LOGGER.info(ringIterator.next().toString()); - } - - LOGGER.info("----------"); - - ItemIterator potionIterator = chest.iterator(ItemType.POTION); - while (potionIterator.hasNext()) { - LOGGER.info(potionIterator.next().toString()); - } - - LOGGER.info("----------"); - - ItemIterator weaponIterator = chest.iterator(ItemType.WEAPON); - while (weaponIterator.hasNext()) { - LOGGER.info(weaponIterator.next().toString()); - } - - LOGGER.info("----------"); - - ItemIterator it = chest.iterator(ItemType.ANY); - while (it.hasNext()) { - LOGGER.info(it.next().toString()); - } + demonstrateBstIterator(); } } diff --git a/iterator/src/main/java/com/iluwatar/iterator/ItemIterator.java b/iterator/src/main/java/com/iluwatar/iterator/ItemIterator.java deleted file mode 100644 index 0eab2f075..000000000 --- a/iterator/src/main/java/com/iluwatar/iterator/ItemIterator.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.iterator; - -/** - * - * ItemIterator interface. - * - */ -public interface ItemIterator { - - boolean hasNext(); - - Item next(); -} diff --git a/iterator/src/main/java/com/iluwatar/iterator/Iterator.java b/iterator/src/main/java/com/iluwatar/iterator/Iterator.java new file mode 100644 index 000000000..b46996968 --- /dev/null +++ b/iterator/src/main/java/com/iluwatar/iterator/Iterator.java @@ -0,0 +1,30 @@ +/** + * The MIT License Copyright (c) 2014-2016 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.iluwatar.iterator; + +/** + * Iterator interface to be implemented by iterators over various data structures + * @param generically typed for various objects + */ +public interface Iterator { + + boolean hasNext(); + + T next(); +} diff --git a/iterator/src/main/java/com/iluwatar/iterator/bst/BstIterator.java b/iterator/src/main/java/com/iluwatar/iterator/bst/BstIterator.java new file mode 100644 index 000000000..81d025df5 --- /dev/null +++ b/iterator/src/main/java/com/iluwatar/iterator/bst/BstIterator.java @@ -0,0 +1,77 @@ +/** + * The MIT License Copyright (c) 2014-2016 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.iluwatar.iterator.bst; + +import com.iluwatar.iterator.Iterator; +import java.util.ArrayDeque; +import java.util.NoSuchElementException; + +/** + * An in-order implementation of a BST Iterator. For example, given a BST with Integer values, + * expect to retrieve TreeNodes according to the Integer's natural ordering (1, 2, 3...) + * + * @param This Iterator has been implemented with generic typing to allow for TreeNodes of + * different value types + */ +public class BstIterator> implements Iterator> { + + private ArrayDeque> pathStack; + + public BstIterator(TreeNode root) { + pathStack = new ArrayDeque<>(); + pushPathToNextSmallest(root); + } + + /** + * This BstIterator manages to use O(h) extra space, where h is the height of the tree It achieves + * this by maintaining a stack of the nodes to handle (pushing all left nodes first), before + * handling self or right node + * + * @param node TreeNode that acts as root of the subtree we're interested in. + */ + private void pushPathToNextSmallest(TreeNode node) { + while (node != null) { + pathStack.push(node); + node = node.getLeft(); + } + } + + /** + * @return true if this iterator has a "next" element + */ + @Override + public boolean hasNext() { + return !pathStack.isEmpty(); + } + + /** + * @return TreeNode next. The next element according to our in-order traversal of the given BST + * @throws NoSuchElementException if this iterator does not have a next element + */ + @Override + public TreeNode next() throws NoSuchElementException { + if (pathStack.isEmpty()) { + throw new NoSuchElementException(); + } + TreeNode next = pathStack.pop(); + pushPathToNextSmallest(next.getRight()); + return next; + } + +} diff --git a/iterator/src/main/java/com/iluwatar/iterator/bst/README.md b/iterator/src/main/java/com/iluwatar/iterator/bst/README.md new file mode 100644 index 000000000..02e8eefcb --- /dev/null +++ b/iterator/src/main/java/com/iluwatar/iterator/bst/README.md @@ -0,0 +1,86 @@ +# BSTIterator +An implementation of the Iterator design pattern, for the Binary Search Tree +data structure. A great explanation of BSTs can be found in this [video tutorial](https://www.youtube.com/watch?v=i_Q0v_Ct5lY). + +### What it Does +This iterator assumes that the given binary search tree inserts nodes of smaller +value to the left, and nodes of larger value to the right of current node. Accordingly, +this iterator will return nodes according to "In Order" binary tree traversal. +This means that given a binary search tree like the following, the iterator would +return values in order: 1, 3, 4, 6, 7, 8, 10, 13, 14. + +![BST](../../../../../../../etc/bst.jpg "Binary Search Tree") + +### How It's Done +**The trivial solution** to a binary search tree iterator would be to construct a List (or similar +linear data structure) when you construct the BSTIterator. This would require traversing the entire +BST, adding each node value to your list as you go. The downside to the trivial solution is twofold. +You're front loading the work by requiring the BSTIterator's constructor to traverse the entire tree, +and you're taking up more memory by maintaining (worst case) every node in the tree in a separate +data structure. In Big O terms, here are the costs, where n is the number of nodes in the tree: +* Constructor Run Time: O(n) +* `next()` Run Time: O(1) +* `hasNext()` Run Time: O(1) +* Extra Space: O(n) + +**A better solution** is to maintain _only_ the path to the next smallest node. For instance, given +the BST above, when you first create your BSTIterator, instead of traversing the entire tree, you +would navigate to the next smallest node (in this case, 1), pushing nodes onto a stack along the way. +Your BSTIterator Constructor would look like: +``` +private ArrayDeque pathStack; + +public BSTIterator(TreeNode root) { + pathStack = new ArrayDeque<>(); + pushPathToNextSmallest(root); +} + +private void pushPathToNextSmallest(TreeNode node) { + while (node != null) { + pathStack.push(node); + node = node.getLeft(); + } +} +``` + +After the constructor is called our BST, your `pathStack` would look like this: + +1\ +3\ +8 + +This way, you're certain of what the next smallest node is because it lives on top of your path +stack. In order to maintain the integrity of this path stack, when you call `next()` and pop a +node off the stack, you must check to see if it has a right child. If it does, then you must follow the right +child's path to the next smallest node (pushing onto your path stack as you go). Given our above example, +calling `next()` on our BSTIterator twice would return node "3". Node "3" has a right child, indicating +a path to a node smaller than 3's parent. In this case, you would push node "6" onto the stack, +and node "4" onto the stack. `next()` would look like this: + +``` +public TreeNode next() throws IllegalStateException { + // If the user calls next() and hasNext() is false + if (pathStack.isEmpty()) { + throw new IllegalStateException(); + } + TreeNode next = pathStack.pop(); + // follow right child to next smallest node + pushPathToNextSmallest(next.getRight()); + return next; +} +``` + +**Key Concept:** The path to the smallest node of a given subtree is navigating straight to the +leftmost node of that subtree. + +In Big O terms, here are the costs for our improved solution, where h is the height of the tree: +* Constructor Run Time: O(h) +* `next()` Amortized Run Time: O(1) +* `hasNext()` Run Time: O(1) +* Extra Space: O(h) + +As you can see, this solution more evenly distributes the work. It yields the same amortized +runtime for `next()`, reduces the run time of the constructor, and uses less extra space. + + + \ No newline at end of file diff --git a/iterator/src/main/java/com/iluwatar/iterator/bst/TreeNode.java b/iterator/src/main/java/com/iluwatar/iterator/bst/TreeNode.java new file mode 100644 index 000000000..a8da74787 --- /dev/null +++ b/iterator/src/main/java/com/iluwatar/iterator/bst/TreeNode.java @@ -0,0 +1,134 @@ +/** + * The MIT License Copyright (c) 2014-2016 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.iluwatar.iterator.bst; + +/** + * TreeNode Class, representing one node in a Binary Search Tree. Allows for a generically typed + * value. + * + * @param generically typed to accept various data types for the val property + */ +public class TreeNode> { + + private T val; + private TreeNode left; + private TreeNode right; + + /** + * Creates a TreeNode with a given value, and null children + * + * @param val The value of the given node + */ + public TreeNode(T val) { + this.val = val; + this.left = null; + this.right = null; + } + + public T getVal() { + return val; + } + + public TreeNode getLeft() { + return left; + } + + private void setLeft(TreeNode left) { + this.left = left; + } + + public TreeNode getRight() { + return right; + } + + private void setRight(TreeNode right) { + this.right = right; + } + + /** + * Inserts new TreeNode based on a given value into the subtree represented by self + * + * @param valToInsert The value to insert as a new TreeNode + */ + public void insert(T valToInsert) { + TreeNode parent = getParentNodeOfValueToBeInserted(valToInsert); + parent.insertNewChild(valToInsert); + } + + /** + * Fetch the Parent TreeNode for a given value to insert into the BST. + * + * @param valToInsert Value of the new TreeNode to be inserted + * @return Parent TreeNode of `valToInsert` + */ + private TreeNode getParentNodeOfValueToBeInserted(T valToInsert) { + TreeNode parent = null; + TreeNode curr = this; + + while (curr != null) { + parent = curr; + curr = curr.traverseOneLevelDown(valToInsert); + } + + return parent; + } + + /** + * Returns left or right child of self based on a value that would be inserted; maintaining the + * integrity of the BST. + * + * @param value The value of the TreeNode that would be inserted beneath self + * @return The child TreeNode of self which represents the subtree where `value` would be inserted + */ + private TreeNode traverseOneLevelDown(T value) { + if (this.isGreaterThan(value)) { + return this.left; + } + return this.right; + } + + /** + * Add a new Child TreeNode of given value to self. WARNING: This method is destructive (will + * overwrite existing tree structure, if any), and should be called only by this class's insert() + * method. + * + * @param valToInsert Value of the new TreeNode to be inserted + */ + private void insertNewChild(T valToInsert) { + if (this.isLessThanOrEqualTo(valToInsert)) { + this.setRight(new TreeNode<>(valToInsert)); + } else { + this.setLeft(new TreeNode<>(valToInsert)); + } + } + + private boolean isGreaterThan(T val) { + return this.val.compareTo(val) > 0; + } + + private boolean isLessThanOrEqualTo(T val) { + return this.val.compareTo(val) < 1; + } + + @Override + public String toString() { + return val.toString(); + } + +} diff --git a/iterator/src/main/java/com/iluwatar/iterator/Item.java b/iterator/src/main/java/com/iluwatar/iterator/list/Item.java similarity index 97% rename from iterator/src/main/java/com/iluwatar/iterator/Item.java rename to iterator/src/main/java/com/iluwatar/iterator/list/Item.java index 47bc11354..7f0f92d99 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/Item.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/Item.java @@ -20,7 +20,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.iterator; +package com.iluwatar.iterator.list; /** * diff --git a/iterator/src/main/java/com/iluwatar/iterator/ItemType.java b/iterator/src/main/java/com/iluwatar/iterator/list/ItemType.java similarity index 97% rename from iterator/src/main/java/com/iluwatar/iterator/ItemType.java rename to iterator/src/main/java/com/iluwatar/iterator/list/ItemType.java index 4cf36926e..e36062681 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/ItemType.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/ItemType.java @@ -20,7 +20,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.iterator; +package com.iluwatar.iterator.list; /** * diff --git a/iterator/src/main/java/com/iluwatar/iterator/TreasureChest.java b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChest.java similarity index 57% rename from iterator/src/main/java/com/iluwatar/iterator/TreasureChest.java rename to iterator/src/main/java/com/iluwatar/iterator/list/TreasureChest.java index 4b9959269..47bc77384 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/TreasureChest.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChest.java @@ -1,34 +1,31 @@ /** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä + * The MIT License Copyright (c) 2014-2016 Ilkka Seppälä * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.iluwatar.iterator; +package com.iluwatar.iterator.list; +import com.iluwatar.iterator.Iterator; import java.util.ArrayList; import java.util.List; /** - * + * * TreasureChest, the collection class. - * + * */ public class TreasureChest { @@ -51,7 +48,7 @@ public class TreasureChest { items.add(new Item(ItemType.WEAPON, "Dagger of poison")); } - ItemIterator iterator(ItemType itemType) { + public Iterator iterator(ItemType itemType) { return new TreasureChestItemIterator(this, itemType); } @@ -59,9 +56,7 @@ public class TreasureChest { * Get all items */ public List getItems() { - List list = new ArrayList<>(); - list.addAll(items); - return list; + return new ArrayList<>(items); } } diff --git a/iterator/src/main/java/com/iluwatar/iterator/TreasureChestItemIterator.java b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChestItemIterator.java similarity index 57% rename from iterator/src/main/java/com/iluwatar/iterator/TreasureChestItemIterator.java rename to iterator/src/main/java/com/iluwatar/iterator/list/TreasureChestItemIterator.java index 9d841259f..ab95d6b4d 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/TreasureChestItemIterator.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChestItemIterator.java @@ -1,35 +1,32 @@ /** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä + * The MIT License Copyright (c) 2014-2016 Ilkka Seppälä * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.iluwatar.iterator; +package com.iluwatar.iterator.list; +import com.iluwatar.iterator.Iterator; import java.util.List; /** - * + * * TreasureChestItemIterator * */ -public class TreasureChestItemIterator implements ItemIterator { +public class TreasureChestItemIterator implements Iterator { private TreasureChest chest; private int idx; @@ -59,7 +56,6 @@ public class TreasureChestItemIterator implements ItemIterator { } private int findNextIdx() { - List items = chest.getItems(); boolean found = false; int tempIdx = idx; diff --git a/iterator/src/test/java/com/iluwatar/iterator/AppTest.java b/iterator/src/test/java/com/iluwatar/iterator/AppTest.java index f448a378e..b7892db5b 100644 --- a/iterator/src/test/java/com/iluwatar/iterator/AppTest.java +++ b/iterator/src/test/java/com/iluwatar/iterator/AppTest.java @@ -1,39 +1,34 @@ /** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is + * The MIT License Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. + *

+ * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + package com.iluwatar.iterator; import org.junit.jupiter.api.Test; /** - * - * Application test - * + * Application Test */ -public class AppTest { +class AppTest { @Test - public void test() { + void testApp() { String[] args = {}; App.main(args); } -} +} \ No newline at end of file diff --git a/iterator/src/test/java/com/iluwatar/iterator/bst/BstIteratorTest.java b/iterator/src/test/java/com/iluwatar/iterator/bst/BstIteratorTest.java new file mode 100644 index 000000000..0e69b341a --- /dev/null +++ b/iterator/src/test/java/com/iluwatar/iterator/bst/BstIteratorTest.java @@ -0,0 +1,99 @@ +/** + * The MIT License Copyright (c) 2014-2016 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.iluwatar.iterator.bst; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; + +import java.util.NoSuchElementException; + +@TestInstance(Lifecycle.PER_CLASS) +class BstIteratorTest { + + private TreeNode nonEmptyRoot; + private TreeNode emptyRoot; + + @BeforeAll + void createTrees() { + nonEmptyRoot = new TreeNode<>(5); + nonEmptyRoot.insert(3); + nonEmptyRoot.insert(7); + nonEmptyRoot.insert(1); + nonEmptyRoot.insert(4); + nonEmptyRoot.insert(6); + + emptyRoot = null; + } + + @Test + void nextForEmptyTree() { + BstIterator iter = new BstIterator<>(emptyRoot); + assertThrows(NoSuchElementException.class, iter::next, + "next() should throw an IllegalStateException if hasNext() is false."); + } + + @Test + void nextOverEntirePopulatedTree() { + BstIterator iter = new BstIterator<>(nonEmptyRoot); + assertEquals(1, iter.next().getVal(), "First Node is 1."); + assertEquals(3, iter.next().getVal(), "Second Node is 3."); + assertEquals(4, iter.next().getVal(), "Third Node is 4."); + assertEquals(5, iter.next().getVal(), "Fourth Node is 5."); + assertEquals(6, iter.next().getVal(), "Fifth Node is 6."); + assertEquals(7, iter.next().getVal(), "Sixth Node is 7."); + } + + @Test + void hasNextForEmptyTree() { + BstIterator iter = new BstIterator<>(emptyRoot); + assertFalse(iter.hasNext(), "hasNext() should return false for empty tree."); + } + + @Test + void hasNextForPopulatedTree() { + BstIterator iter = new BstIterator<>(nonEmptyRoot); + assertTrue(iter.hasNext(), "hasNext() should return true for populated tree."); + } + + @Test + void nextAndHasNextOverEntirePopulatedTree() { + BstIterator iter = new BstIterator<>(nonEmptyRoot); + assertTrue(iter.hasNext(), "Iterator hasNext() should be true."); + assertEquals(1, iter.next().getVal(), "First Node is 1."); + assertTrue(iter.hasNext(), "Iterator hasNext() should be true."); + assertEquals(3, iter.next().getVal(), "Second Node is 3."); + assertTrue(iter.hasNext(), "Iterator hasNext() should be true."); + assertEquals(4, iter.next().getVal(), "Third Node is 4."); + assertTrue(iter.hasNext(), "Iterator hasNext() should be true."); + assertEquals(5, iter.next().getVal(), "Fourth Node is 5."); + assertTrue(iter.hasNext(), "Iterator hasNext() should be true."); + assertEquals(6, iter.next().getVal(), "Fifth Node is 6."); + assertTrue(iter.hasNext(), "Iterator hasNext() should be true."); + assertEquals(7, iter.next().getVal(), "Sixth Node is 7."); + assertFalse(iter.hasNext(), "Iterator hasNext() should be false, end of tree."); + } + +} diff --git a/iterator/src/test/java/com/iluwatar/iterator/TreasureChestTest.java b/iterator/src/test/java/com/iluwatar/iterator/list/TreasureChestTest.java similarity index 76% rename from iterator/src/test/java/com/iluwatar/iterator/TreasureChestTest.java rename to iterator/src/test/java/com/iluwatar/iterator/list/TreasureChestTest.java index 665666aa7..e15f130b7 100644 --- a/iterator/src/test/java/com/iluwatar/iterator/TreasureChestTest.java +++ b/iterator/src/test/java/com/iluwatar/iterator/list/TreasureChestTest.java @@ -1,37 +1,33 @@ /** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä + * The MIT License Copyright (c) 2014-2016 Ilkka Seppälä * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.iluwatar.iterator; - -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.ArrayList; -import java.util.List; +package com.iluwatar.iterator.list; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.fail; +import com.iluwatar.iterator.Iterator; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + /** * Date: 12/14/15 - 2:58 PM * @@ -60,13 +56,14 @@ public class TreasureChestTest { } /** - * Test if the expected item can be retrieved from the chest using the {@link ItemIterator} + * Test if the expected item can be retrieved from the chest using the {@link + * TreasureChestItemIterator} */ @ParameterizedTest @MethodSource("dataProvider") public void testIterator(Item expectedItem) { final TreasureChest chest = new TreasureChest(); - final ItemIterator iterator = chest.iterator(expectedItem.getType()); + final Iterator iterator = chest.iterator(expectedItem.getType()); assertNotNull(iterator); while (iterator.hasNext()) {