summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/funcdata
diff options
context:
space:
mode:
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/funcdata')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java50
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java102
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java52
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java29
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/IList.java7
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java2
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java2
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java54
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeLeaf.java49
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java114
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;
+ }
}