diff options
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/funcdata')
10 files changed, 351 insertions, 110 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java index 49382bc..caa487c 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java @@ -23,7 +23,8 @@ class ExtendedMap<KeyType, ValueType> implements IMap<KeyType, ValueType> { @Override public boolean containsKey(KeyType key) { - if(store.containsKey(key)) return true; + if (store.containsKey(key)) + return true; return delegate.containsKey(key); } @@ -56,7 +57,8 @@ class ExtendedMap<KeyType, ValueType> implements IMap<KeyType, ValueType> { @Override public ValueType get(KeyType key) { - if(store.containsKey(key)) return store.get(key); + if (store.containsKey(key)) + return store.get(key); return delegate.get(key); } @@ -83,8 +85,9 @@ class ExtendedMap<KeyType, ValueType> implements IMap<KeyType, ValueType> { @Override public ValueType remove(KeyType key) { - if(!store.containsKey(key)) return delegate.remove(key); - + if (!store.containsKey(key)) + return delegate.remove(key); + return store.remove(key); } @@ -92,4 +95,43 @@ class ExtendedMap<KeyType, ValueType> implements IMap<KeyType, ValueType> { public IList<ValueType> valueList() { return ListUtils.mergeLists(store.valueList(), delegate.valueList()); } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((delegate == null) ? 0 : delegate.hashCode()); + result = prime * result + ((store == null) ? 0 : store.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof ExtendedMap)) + return false; + + ExtendedMap<?, ?> other = (ExtendedMap<?, ?>) obj; + + if (delegate == null) { + if (other.delegate != null) + return false; + } else if (!delegate.equals(other.delegate)) + return false; + if (store == null) { + if (other.store != null) + return false; + } else if (!store.equals(other.store)) + return false; + + return true; + } + + @Override + public String toString() { + return String.format("ExtendedMap [delegate=%s, store=%s]", delegate, store); + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java index 1e52d05..7627bdf 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java @@ -54,7 +54,7 @@ public class FunctionalList<E> implements Cloneable, IList<E> { public FunctionalList(E... items) { wrapped = new ArrayList<>(items.length); - for(E item : items) { + for (E item : items) { wrapped.add(item); } } @@ -78,7 +78,8 @@ public class FunctionalList<E> implements Cloneable, IList<E> { * The list to use as a backing list. */ public FunctionalList(List<E> backing) { - if(backing == null) throw new NullPointerException("Backing list must be non-null"); + if (backing == null) + throw new NullPointerException("Backing list must be non-null"); wrapped = backing; } @@ -90,11 +91,12 @@ public class FunctionalList<E> implements Cloneable, IList<E> { @Override public boolean allMatch(Predicate<E> predicate) { - if(predicate == null) throw new NullPointerException("Predicate must be non-null"); + if (predicate == null) + throw new NullPointerException("Predicate must be non-null"); - for(E item : wrapped) { - if(!predicate.test(item)) // We've found a non-matching - // item + for (E item : wrapped) { + if (!predicate.test(item)) + // We've found a non-matching item return false; } @@ -104,10 +106,12 @@ public class FunctionalList<E> implements Cloneable, IList<E> { @Override public boolean anyMatch(Predicate<E> predicate) { - if(predicate == null) throw new NullPointerException("Predicate must be not null"); + if (predicate == null) + throw new NullPointerException("Predicate must be not null"); - for(E item : wrapped) { - if(predicate.test(item)) // We've found a matching item + for (E item : wrapped) { + if (predicate.test(item)) + // We've found a matching item return true; } @@ -126,7 +130,7 @@ public class FunctionalList<E> implements Cloneable, IList<E> { public IList<E> clone() { IList<E> cloned = new FunctionalList<>(); - for(E element : wrapped) { + for (E element : wrapped) { cloned.add(element); } @@ -135,16 +139,18 @@ public class FunctionalList<E> implements Cloneable, IList<E> { @Override public <T, F> IList<F> combineWith(IList<T> rightList, BiFunction<E, T, F> itemCombiner) { - if(rightList == null) + if (rightList == null) throw new NullPointerException("Target combine list must not be null"); - else if(itemCombiner == null) throw new NullPointerException("Combiner must not be null"); + else if (itemCombiner == null) + throw new NullPointerException("Combiner must not be null"); IList<F> returned = new FunctionalList<>(); // Get the iterator for the other list Iterator<T> rightIterator = rightList.toIterable().iterator(); - for(Iterator<E> leftIterator = wrapped.iterator(); leftIterator.hasNext() && rightIterator.hasNext();) { + for (Iterator<E> leftIterator = wrapped.iterator(); leftIterator.hasNext() + && rightIterator.hasNext();) { // Add the transformed items to the result list E leftVal = leftIterator.next(); T rightVal = rightIterator.next(); @@ -163,21 +169,24 @@ public class FunctionalList<E> implements Cloneable, IList<E> { @Override public E first() { - if(wrapped.size() < 1) throw new NoSuchElementException("Attempted to get first element of empty list"); + if (wrapped.size() < 1) + throw new NoSuchElementException("Attempted to get first element of empty list"); return wrapped.get(0); } @Override public <T> IList<T> flatMap(Function<E, IList<T>> expander) { - if(expander == null) throw new NullPointerException("Expander must not be null"); + if (expander == null) + throw new NullPointerException("Expander must not be null"); IList<T> returned = new FunctionalList<>(this.wrapped.size()); forEach(element -> { IList<T> expandedElement = expander.apply(element); - if(expandedElement == null) throw new NullPointerException("Expander returned null list"); + if (expandedElement == null) + throw new NullPointerException("Expander returned null list"); // Add each element to the returned list expandedElement.forEach(returned::add); @@ -188,14 +197,16 @@ public class FunctionalList<E> implements Cloneable, IList<E> { @Override public void forEach(Consumer<? super E> action) { - if(action == null) throw new NullPointerException("Action is null"); + if (action == null) + throw new NullPointerException("Action is null"); wrapped.forEach(action); } @Override public void forEachIndexed(BiConsumer<Integer, E> indexedAction) { - if(indexedAction == null) throw new NullPointerException("Action must not be null"); + if (indexedAction == null) + throw new NullPointerException("Action must not be null"); // This is held b/c ref'd variables must be final/effectively // final @@ -226,12 +237,13 @@ public class FunctionalList<E> implements Cloneable, IList<E> { @Override public IList<E> getMatching(Predicate<E> predicate) { - if(predicate == null) throw new NullPointerException("Predicate must not be null"); + if (predicate == null) + throw new NullPointerException("Predicate must not be null"); IList<E> returned = new FunctionalList<>(); wrapped.forEach((element) -> { - if(predicate.test(element)) { + if (predicate.test(element)) { // The item matches, so add it to the returned // list returned.add(element); @@ -260,7 +272,8 @@ public class FunctionalList<E> implements Cloneable, IList<E> { @Override public <T> IList<T> map(Function<E, T> elementTransformer) { - if(elementTransformer == null) throw new NullPointerException("Transformer must be not null"); + if (elementTransformer == null) + throw new NullPointerException("Transformer must be not null"); IList<T> returned = new FunctionalList<>(this.wrapped.size()); @@ -279,25 +292,28 @@ public class FunctionalList<E> implements Cloneable, IList<E> { @Override public IList<IList<E>> partition(int numberPerPartition) { - if(numberPerPartition < 1 || numberPerPartition > wrapped.size()) - throw new IllegalArgumentException("" + numberPerPartition - + " is an invalid partition size. Must be between 1 and " + wrapped.size()); + if (numberPerPartition < 1 || numberPerPartition > wrapped.size()) { + String fmt = "%s is an invalid partition size. Must be between 1 and %d"; + String msg = String.format(fmt, numberPerPartition, wrapped.size()); + + throw new IllegalArgumentException(msg); + } IList<IList<E>> returned = new FunctionalList<>(); // The current partition being filled IHolder<IList<E>> currentPartition = new Identity<>(new FunctionalList<>()); - this.forEach((element) -> { - if(isPartitionFull(numberPerPartition, currentPartition)) { + this.forEach(element -> { + if (isPartitionFull(numberPerPartition, currentPartition)) { // Add the partition to the list - returned.add(currentPartition.unwrap((partition) -> partition)); + returned.add(currentPartition.unwrap(partition -> partition)); // Start a new partition - currentPartition.transform((partition) -> new FunctionalList<>()); + currentPartition.transform(partition -> new FunctionalList<>()); } else { // Add the element to the current partition - currentPartition.unwrap((partition) -> partition.add(element)); + currentPartition.unwrap(partition -> partition.add(element)); } }); @@ -311,7 +327,8 @@ public class FunctionalList<E> implements Cloneable, IList<E> { @Override public E randItem(Function<Integer, Integer> rnd) { - if(rnd == null) throw new NullPointerException("Random source must not be null"); + if (rnd == null) + throw new NullPointerException("Random source must not be null"); int randomIndex = rnd.apply(wrapped.size()); @@ -321,16 +338,17 @@ public class FunctionalList<E> implements Cloneable, IList<E> { @Override public <T, F> F reduceAux(T initialValue, BiFunction<E, T, T> stateAccumulator, Function<T, F> resultTransformer) { - if(stateAccumulator == null) + if (stateAccumulator == null) throw new NullPointerException("Accumulator must not be null"); - else if(resultTransformer == null) throw new NullPointerException("Transformer must not be null"); + else if (resultTransformer == null) + throw new NullPointerException("Transformer must not be null"); // The current collapsed list IHolder<T> currentState = new Identity<>(initialValue); wrapped.forEach(element -> { // Accumulate a new value into the state - currentState.transform((state) -> stateAccumulator.apply(element, state)); + currentState.transform(state -> stateAccumulator.apply(element, state)); }); // Convert the state to its final value @@ -339,14 +357,15 @@ public class FunctionalList<E> implements Cloneable, IList<E> { @Override public boolean removeIf(Predicate<E> removePredicate) { - if(removePredicate == null) throw new NullPointerException("Predicate must be non-null"); + if (removePredicate == null) + throw new NullPointerException("Predicate must be non-null"); return wrapped.removeIf(removePredicate); } @Override public void removeMatching(E desiredElement) { - removeIf((element) -> element.equals(desiredElement)); + removeIf(element -> element.equals(desiredElement)); } @Override @@ -359,7 +378,7 @@ public class FunctionalList<E> implements Cloneable, IList<E> { // Search our internal list int foundIndex = Collections.binarySearch(wrapped, searchKey, comparator); - if(foundIndex >= 0) // We found a matching element + if (foundIndex >= 0) // We found a matching element return wrapped.get(foundIndex); // We didn't find an element @@ -391,19 +410,21 @@ public class FunctionalList<E> implements Cloneable, IList<E> { public String toString() { int lSize = getSize(); - if(lSize == 0) return "()"; + if (lSize == 0) + return "()"; StringBuilder sb = new StringBuilder("("); Iterator<E> itr = toIterable().iterator(); E itm = itr.next(); int i = 0; - if(lSize == 1) return "(" + itm + ")"; + if (lSize == 1) + return "(" + itm + ")"; - for(E item : toIterable()) { + for (E item : toIterable()) { sb.append(item.toString()); - if(i < lSize - 1) { + if (i < lSize - 1) { sb.append(", "); } @@ -411,6 +432,7 @@ public class FunctionalList<E> implements Cloneable, IList<E> { } sb.append(")"); + return sb.toString(); } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java index b4e5981..62c39af 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java @@ -38,7 +38,7 @@ public class FunctionalMap<KeyType, ValueType> implements IMap<KeyType, ValueTyp public FunctionalMap(IPair<KeyType, ValueType>... entries) { this(); - for(IPair<KeyType, ValueType> entry : entries) { + for (IPair<KeyType, ValueType> entry : entries) { entry.doWith((key, val) -> { wrappedMap.put(key, val); }); @@ -52,7 +52,8 @@ public class FunctionalMap<KeyType, ValueType> implements IMap<KeyType, ValueTyp * The map to wrap */ public FunctionalMap(Map<KeyType, ValueType> wrap) { - if(wrap == null) throw new NullPointerException("Map to wrap must not be null"); + if (wrap == null) + throw new NullPointerException("Map to wrap must not be null"); wrappedMap = wrap; } @@ -89,10 +90,14 @@ public class FunctionalMap<KeyType, ValueType> implements IMap<KeyType, ValueTyp @Override public ValueType get(KeyType key) { - if(key == null) throw new NullPointerException("Key must not be null"); + if (key == null) + throw new NullPointerException("Key must not be null"); - if(!wrappedMap.containsKey(key)) - throw new IllegalArgumentException("Key " + key + " is not present in the map"); + if (!wrappedMap.containsKey(key)) { + String msg = String.format("Key %s is not present in the map", key); + + throw new IllegalArgumentException(msg); + } return wrappedMap.get(key); } @@ -106,7 +111,7 @@ public class FunctionalMap<KeyType, ValueType> implements IMap<KeyType, ValueTyp public IList<KeyType> keyList() { FunctionalList<KeyType> keys = new FunctionalList<>(); - wrappedMap.keySet().forEach((key) -> { + wrappedMap.keySet().forEach(key -> { keys.add(key); }); @@ -115,14 +120,16 @@ public class FunctionalMap<KeyType, ValueType> implements IMap<KeyType, ValueTyp @Override public <MappedValue> IMap<KeyType, MappedValue> transform(Function<ValueType, MappedValue> transformer) { - if(transformer == null) throw new NullPointerException("Transformer must not be null"); + if (transformer == null) + throw new NullPointerException("Transformer must not be null"); return new TransformedValueMap<>(this, transformer); } @Override public ValueType put(KeyType key, ValueType val) { - if(key == null) throw new NullPointerException("Key must not be null"); + if (key == null) + throw new NullPointerException("Key must not be null"); return wrappedMap.put(key, val); } @@ -141,10 +148,37 @@ public class FunctionalMap<KeyType, ValueType> implements IMap<KeyType, ValueTyp public IList<ValueType> valueList() { FunctionalList<ValueType> values = new FunctionalList<>(); - wrappedMap.values().forEach((value) -> { + wrappedMap.values().forEach(value -> { values.add(value); }); return values; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((wrappedMap == null) ? 0 : wrappedMap.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof FunctionalMap)) + return false; + + FunctionalMap<?, ?> other = (FunctionalMap<?, ?>) obj; + + if (wrappedMap == null) { + if (other.wrappedMap != null) + return false; + } else if (!wrappedMap.equals(other.wrappedMap)) + return false; + return true; + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java index b7e3f30..4723bcd 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java @@ -19,7 +19,8 @@ public class FunctionalStringTokenizer { * @return A new tokenizer that splits the provided string on spaces. */ public static FunctionalStringTokenizer fromString(String strang) { - if(strang == null) throw new NullPointerException("String to tokenize must be non-null"); + if (strang == null) + throw new NullPointerException("String to tokenize must be non-null"); return new FunctionalStringTokenizer(new StringTokenizer(strang, " ")); } @@ -36,7 +37,8 @@ public class FunctionalStringTokenizer { * The string to tokenize */ public FunctionalStringTokenizer(String inp) { - if(inp == null) throw new NullPointerException("String to tokenize must be non-null"); + if (inp == null) + throw new NullPointerException("String to tokenize must be non-null"); this.input = new StringTokenizer(inp); } @@ -51,9 +53,10 @@ public class FunctionalStringTokenizer { * The set of separating tokens to use for splitting */ public FunctionalStringTokenizer(String input, String seperators) { - if(input == null) + if (input == null) throw new NullPointerException("String to tokenize must not be null"); - else if(seperators == null) throw new NullPointerException("Tokens to split on must not be null"); + else if (seperators == null) + throw new NullPointerException("Tokens to split on must not be null"); this.input = new StringTokenizer(input, seperators); } @@ -65,7 +68,8 @@ public class FunctionalStringTokenizer { * The non-functional string tokenizer to wrap */ public FunctionalStringTokenizer(StringTokenizer toWrap) { - if(toWrap == null) throw new NullPointerException("Wrapped tokenizer must not be null"); + if (toWrap == null) + throw new NullPointerException("Wrapped tokenizer must not be null"); this.input = toWrap; } @@ -77,9 +81,10 @@ public class FunctionalStringTokenizer { * The action to execute for each token */ public void forEachToken(Consumer<String> action) { - if(action == null) throw new NullPointerException("Action must not be null"); + if (action == null) + throw new NullPointerException("Action must not be null"); - while(input.hasMoreTokens()) { + while (input.hasMoreTokens()) { action.accept(input.nextToken()); } } @@ -110,7 +115,7 @@ public class FunctionalStringTokenizer { * @return The next token from the tokenizer */ public String nextToken() { - if(input.hasMoreTokens()) // Return the next available token + if (input.hasMoreTokens()) // Return the next available token return input.nextToken(); // Return no token @@ -138,7 +143,8 @@ public class FunctionalStringTokenizer { * @return A list containing all of the converted tokens. */ public <E> IList<E> toList(Function<String, E> transformer) { - if(transformer == null) throw new NullPointerException("Transformer must not be null"); + if (transformer == null) + throw new NullPointerException("Transformer must not be null"); IList<E> returned = new FunctionalList<>(); @@ -151,4 +157,9 @@ public class FunctionalStringTokenizer { return returned; } + + @Override + public String toString() { + return String.format("FunctionalStringTokenizer [input=%s]", input); + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IList.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IList.java index 95f4813..cf60ed6 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IList.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IList.java @@ -38,7 +38,7 @@ public interface IList<ContainedType> extends Iterable<ContainedType> { * otherwise */ default boolean addAll(IList<ContainedType> items) { - return items.map(this::add).anyMatch((bl) -> bl == false); + return items.map(this::add).anyMatch(bl -> bl == false); } /** @@ -77,7 +77,8 @@ public interface IList<ContainedType> extends Iterable<ContainedType> { Collector<ContainedType, StateType, ReducedType> collector) { BiConsumer<StateType, ContainedType> accumulator = collector.accumulator(); - return reduceAux(collector.supplier().get(), (value, state) -> { + StateType initial = collector.supplier().get(); + return reduceAux(initial, (value, state) -> { accumulator.accept(state, value); return state; @@ -243,7 +244,7 @@ public interface IList<ContainedType> extends Iterable<ContainedType> { * @return A random item from the list */ default ContainedType randItem() { - return randItem((num) -> (int) (Math.random() * num)); + return randItem(num -> (int) (Math.random() * num)); } /** diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java index 6bb5de6..e58409e 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java @@ -112,7 +112,7 @@ public interface IMap<KeyType, ValueType> { * Delete all the values in the map. */ default void clear() { - keyList().forEach((key) -> remove(key)); + keyList().forEach(key -> remove(key)); } /** diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java index 89ea96d..43bd4d0 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java @@ -54,7 +54,7 @@ final class TransformedValueMap<OldKey, OldValue, NewValue> implements IMap<OldK @Override public void forEachValue(Consumer<NewValue> action) { - backing.forEachValue((value) -> { + backing.forEachValue(value -> { action.accept(transformer.apply(value)); }); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java index 060b3f5..e85ae34 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java @@ -39,7 +39,8 @@ public class BinarySearchTree<T> { * The thing to use for comparing elements */ public BinarySearchTree(Comparator<T> cmp) { - if(cmp == null) throw new NullPointerException("Comparator must not be null"); + if (cmp == null) + throw new NullPointerException("Comparator must not be null"); elementCount = 0; comparator = cmp; @@ -54,7 +55,7 @@ public class BinarySearchTree<T> { public void addNode(T element) { elementCount++; - if(root == null) { + if (root == null) { root = new BinarySearchTreeNode<>(element, null, null); } else { root.add(element, comparator); @@ -95,8 +96,8 @@ public class BinarySearchTree<T> { int pivotAdjustment = 0; // Add elements until there aren't any left - while(adjustedPivotInBounds(elements, pivot, pivotAdjustment)) { - if(root == null) { + while (adjustedPivotInBounds(elements, pivot, pivotAdjustment)) { + if (root == null) { // Create a new root element root = new BinarySearchTreeNode<>(elements.getByIndex(pivot), null, null); } else { @@ -112,9 +113,9 @@ public class BinarySearchTree<T> { } // Add any trailing unbalanced elements - if(pivot - pivotAdjustment >= 0) { + if (pivot - pivotAdjustment >= 0) { root.add(elements.getByIndex(pivot - pivotAdjustment), comparator); - } else if(pivot + pivotAdjustment < elements.getSize()) { + } else if (pivot + pivotAdjustment < elements.getSize()) { root.add(elements.getByIndex(pivot + pivotAdjustment), comparator); } } @@ -163,9 +164,10 @@ public class BinarySearchTree<T> { * The function to use until it fails */ public void traverse(TreeLinearizationMethod linearizationMethod, Predicate<T> traversalPredicate) { - if(linearizationMethod == null) + if (linearizationMethod == null) throw new NullPointerException("Linearization method must not be null"); - else if(traversalPredicate == null) throw new NullPointerException("Predicate must not be nulls"); + else if (traversalPredicate == null) + throw new NullPointerException("Predicate must not be nulls"); root.forEach(linearizationMethod, traversalPredicate); } @@ -188,4 +190,40 @@ public class BinarySearchTree<T> { // Add the nodes to the tree in the order they were inserted nodes.forEach(node -> addNode(node)); } + + @Override + public String toString() { + return String.format("BinarySearchTree [elementCount=%s, root='%s']", elementCount, root); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + elementCount; + result = prime * result + ((root == null) ? 0 : root.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof BinarySearchTree<?>)) + return false; + + BinarySearchTree<?> other = (BinarySearchTree<?>) obj; + + if (elementCount != other.elementCount) + return false; + if (root == null) { + if (other.root != null) + return false; + } else if (!root.equals(other.root)) + return false; + + return true; + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeLeaf.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeLeaf.java index 2696577..fe30dad 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeLeaf.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeLeaf.java @@ -41,7 +41,8 @@ public class BinarySearchTreeLeaf<T> implements ITreePart<T> { @Override public <E> E collapse(Function<T, E> leafTransformer, BiFunction<E, E, E> branchCollapser) { - if(leafTransformer == null) throw new NullPointerException("Transformer must not be null"); + if (leafTransformer == null) + throw new NullPointerException("Transformer must not be null"); return leafTransformer.apply(data); } @@ -58,16 +59,17 @@ public class BinarySearchTreeLeaf<T> implements ITreePart<T> { @Override public void delete(T element, Comparator<T> comparator) { - if(data.equals(element)) { + if (data.equals(element)) { isDeleted = true; } } @Override public boolean directedWalk(DirectedWalkFunction<T> treeWalker) { - if(treeWalker == null) throw new NullPointerException("Tree walker must not be null"); + if (treeWalker == null) + throw new NullPointerException("Tree walker must not be null"); - switch(treeWalker.walk(data)) { + switch (treeWalker.walk(data)) { case SUCCESS: return true; // We don't have any children to care about @@ -81,8 +83,45 @@ public class BinarySearchTreeLeaf<T> implements ITreePart<T> { @Override public boolean forEach(TreeLinearizationMethod linearizationMethod, Predicate<T> traversalPredicate) { - if(traversalPredicate == null) throw new NullPointerException("Predicate must not be null"); + if (traversalPredicate == null) + throw new NullPointerException("Predicate must not be null"); return traversalPredicate.test(data); } + + @Override + public String toString() { + return String.format("BinarySearchTreeLeaf [data='%s', isDeleted=%s]", data, isDeleted); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((data == null) ? 0 : data.hashCode()); + result = prime * result + (isDeleted ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof BinarySearchTreeLeaf<?>)) + return false; + + BinarySearchTreeLeaf<?> other = (BinarySearchTreeLeaf<?>) obj; + + if (data == null) { + if (other.data != null) + return false; + } else if (!data.equals(other.data)) + return false; + if (isDeleted != other.isDeleted) + return false; + + return true; + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java index 4fe9de3..527f221 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java @@ -47,24 +47,25 @@ public class BinarySearchTreeNode<T> extends BinarySearchTreeLeaf<T> { @Override public void add(T element, Comparator<T> comparator) { - if(comparator == null) throw new NullPointerException("Comparator must not be null"); + if (comparator == null) + throw new NullPointerException("Comparator must not be null"); - switch(comparator.compare(data, element)) { + switch (comparator.compare(data, element)) { case -1: - if(left == null) { + if (left == null) { left = new BinarySearchTreeNode<>(element, null, null); } else { left.add(element, comparator); } break; case 0: - if(isDeleted) { + if (isDeleted) { isDeleted = false; } else throw new IllegalArgumentException("Can't add duplicate values"); break; case 1: - if(right == null) { + if (right == null) { right = new BinarySearchTreeNode<>(element, null, null); } else { right.add(element, comparator); @@ -77,15 +78,15 @@ public class BinarySearchTreeNode<T> extends BinarySearchTreeLeaf<T> { @Override public <E> E collapse(Function<T, E> nodeCollapser, BiFunction<E, E, E> branchCollapser) { - if(nodeCollapser == null || branchCollapser == null) + if (nodeCollapser == null || branchCollapser == null) throw new NullPointerException("Collapser must not be null"); E collapsedNode = nodeCollapser.apply(data); - if(left != null) { + if (left != null) { E collapsedLeftBranch = left.collapse(nodeCollapser, branchCollapser); - if(right != null) { + if (right != null) { E collapsedRightBranch = right.collapse(nodeCollapser, branchCollapser); E collapsedBranches = branchCollapser.apply(collapsedLeftBranch, collapsedRightBranch); @@ -96,7 +97,7 @@ public class BinarySearchTreeNode<T> extends BinarySearchTreeLeaf<T> { return branchCollapser.apply(collapsedNode, collapsedLeftBranch); } - if(right != null) { + if (right != null) { E collapsedRightBranch = right.collapse(nodeCollapser, branchCollapser); return branchCollapser.apply(collapsedNode, collapsedRightBranch); @@ -107,10 +108,11 @@ public class BinarySearchTreeNode<T> extends BinarySearchTreeLeaf<T> { @Override public boolean contains(T element, Comparator<T> comparator) { - if(comparator == null) throw new NullPointerException("Comparator must not be null"); + if (comparator == null) + throw new NullPointerException("Comparator must not be null"); return directedWalk(currentElement -> { - switch(comparator.compare(element, currentElement)) { + switch (comparator.compare(element, currentElement)) { case -1: return LEFT; case 0: @@ -125,10 +127,11 @@ public class BinarySearchTreeNode<T> extends BinarySearchTreeLeaf<T> { @Override public void delete(T element, Comparator<T> comparator) { - if(comparator == null) throw new NullPointerException("Comparator must not be null"); + if (comparator == null) + throw new NullPointerException("Comparator must not be null"); directedWalk(currentElement -> { - switch(comparator.compare(data, element)) { + switch (comparator.compare(data, element)) { case -1: return left == null ? FAILURE : LEFT; case 0: @@ -144,9 +147,10 @@ public class BinarySearchTreeNode<T> extends BinarySearchTreeLeaf<T> { @Override public boolean directedWalk(DirectedWalkFunction<T> treeWalker) { - if(treeWalker == null) throw new NullPointerException("Walker must not be null"); + if (treeWalker == null) + throw new NullPointerException("Walker must not be null"); - switch(treeWalker.walk(data)) { + switch (treeWalker.walk(data)) { case SUCCESS: return true; case LEFT: @@ -162,11 +166,12 @@ public class BinarySearchTreeNode<T> extends BinarySearchTreeLeaf<T> { @Override public boolean forEach(TreeLinearizationMethod linearizationMethod, Predicate<T> traversalPredicate) { - if(linearizationMethod == null) + if (linearizationMethod == null) throw new NullPointerException("Linearization method must not be null"); - else if(traversalPredicate == null) throw new NullPointerException("Predicate must not be null"); + else if (traversalPredicate == null) + throw new NullPointerException("Predicate must not be null"); - switch(linearizationMethod) { + switch (linearizationMethod) { case PREORDER: return preorderTraverse(linearizationMethod, traversalPredicate); case INORDER: @@ -180,33 +185,42 @@ public class BinarySearchTreeNode<T> extends BinarySearchTreeLeaf<T> { } private boolean inorderTraverse(TreeLinearizationMethod linearizationMethod, Predicate<T> traversalPredicate) { - if(!traverseLeftBranch(linearizationMethod, traversalPredicate)) return false; + if (!traverseLeftBranch(linearizationMethod, traversalPredicate)) + return false; - if(!traverseElement(traversalPredicate)) return false; + if (!traverseElement(traversalPredicate)) + return false; - if(!traverseRightBranch(linearizationMethod, traversalPredicate)) return false; + if (!traverseRightBranch(linearizationMethod, traversalPredicate)) + return false; return true; } private boolean postorderTraverse(TreeLinearizationMethod linearizationMethod, Predicate<T> traversalPredicate) { - if(!traverseLeftBranch(linearizationMethod, traversalPredicate)) return false; + if (!traverseLeftBranch(linearizationMethod, traversalPredicate)) + return false; - if(!traverseRightBranch(linearizationMethod, traversalPredicate)) return false; + if (!traverseRightBranch(linearizationMethod, traversalPredicate)) + return false; - if(!traverseElement(traversalPredicate)) return false; + if (!traverseElement(traversalPredicate)) + return false; return true; } private boolean preorderTraverse(TreeLinearizationMethod linearizationMethod, Predicate<T> traversalPredicate) { - if(!traverseElement(traversalPredicate)) return false; + if (!traverseElement(traversalPredicate)) + return false; - if(!traverseLeftBranch(linearizationMethod, traversalPredicate)) return false; + if (!traverseLeftBranch(linearizationMethod, traversalPredicate)) + return false; - if(!traverseRightBranch(linearizationMethod, traversalPredicate)) return false; + if (!traverseRightBranch(linearizationMethod, traversalPredicate)) + return false; return true; } @@ -214,7 +228,7 @@ public class BinarySearchTreeNode<T> extends BinarySearchTreeLeaf<T> { private boolean traverseElement(Predicate<T> traversalPredicate) { boolean nodeSuccesfullyTraversed; - if(isDeleted) { + if (isDeleted) { nodeSuccesfullyTraversed = true; } else { nodeSuccesfullyTraversed = traversalPredicate.test(data); @@ -227,7 +241,7 @@ public class BinarySearchTreeNode<T> extends BinarySearchTreeLeaf<T> { Predicate<T> traversalPredicate) { boolean leftSuccesfullyTraversed; - if(left == null) { + if (left == null) { leftSuccesfullyTraversed = true; } else { leftSuccesfullyTraversed = left.forEach(linearizationMethod, traversalPredicate); @@ -240,7 +254,7 @@ public class BinarySearchTreeNode<T> extends BinarySearchTreeLeaf<T> { Predicate<T> traversalPredicate) { boolean rightSuccesfullyTraversed; - if(right == null) { + if (right == null) { rightSuccesfullyTraversed = true; } else { rightSuccesfullyTraversed = right.forEach(linearizationMethod, traversalPredicate); @@ -248,4 +262,44 @@ public class BinarySearchTreeNode<T> extends BinarySearchTreeLeaf<T> { return rightSuccesfullyTraversed; } + + @Override + public String toString() { + return String.format("BinarySearchTreeNode [left='%s', right='%s']", left, right); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((left == null) ? 0 : left.hashCode()); + result = prime * result + ((right == null) ? 0 : right.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (!(obj instanceof BinarySearchTreeNode<?>)) + return false; + + BinarySearchTreeNode<?> other = (BinarySearchTreeNode<?>) obj; + + if (left == null) { + if (other.left != null) + return false; + } else if (!left.equals(other.left)) + return false; + + if (right == null) { + if (other.right != null) + return false; + } else if (!right.equals(other.right)) + return false; + + return true; + } } |
