summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/funcdata
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2016-04-03 19:22:48 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2016-04-03 19:22:48 -0400
commit1c8bc7132d980c1ff2dbd6b9af579c3b2fd8c63e (patch)
treea29777f07ebd81fbef61b5ae02f13f1a9d8f65a2 /BJC-Utils2/src/main/java/bjc/utils/funcdata
parenta023de85aa08c8f2b8b2441c6b14064eabee2775 (diff)
General code refactoring and maintenance
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/funcdata')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java123
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java151
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java47
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java11
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeLeaf.java12
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java27
6 files changed, 347 insertions, 24 deletions
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 a260d78..ff02515 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java
@@ -1,10 +1,10 @@
package bjc.utils.funcdata;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
+import java.util.NoSuchElementException;
import java.util.Random;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
@@ -16,6 +16,8 @@ import bjc.utils.data.GenHolder;
import bjc.utils.data.IHolder;
import bjc.utils.data.Pair;
+import java.util.ArrayList;
+
/**
* A wrapper over another list that provides eager functional operations
* over it. Differs from a stream in every way except for the fact that
@@ -62,6 +64,10 @@ public class FunctionalList<E> implements Cloneable {
* The source for a backing list
*/
public FunctionalList(FunctionalList<E> sourceList) {
+ if (sourceList == null) {
+ throw new NullPointerException("Source list must be non-null");
+ }
+
// Find out if this should make a copy of the source's wrapped list
// instead.
//
@@ -88,6 +94,11 @@ public class FunctionalList<E> implements Cloneable {
* The list to use as a backing list.
*/
public FunctionalList(List<E> backingList) {
+ if (backingList == null) {
+ throw new NullPointerException(
+ "Backing list must be non-null");
+ }
+
wrappedList = backingList;
}
@@ -112,6 +123,10 @@ public class FunctionalList<E> implements Cloneable {
* predicate.
*/
public boolean allMatch(Predicate<E> matchPredicate) {
+ if (matchPredicate == null) {
+ throw new NullPointerException("Predicate must be non-null");
+ }
+
for (E item : wrappedList) {
if (!matchPredicate.test(item)) {
// We've found a non-matching item
@@ -132,6 +147,10 @@ public class FunctionalList<E> implements Cloneable {
* predicate.
*/
public boolean anyMatch(Predicate<E> matchPredicate) {
+ if (matchPredicate == null) {
+ throw new NullPointerException("Predicate must be not null");
+ }
+
for (E item : wrappedList) {
if (matchPredicate.test(item)) {
// We've found a matching item
@@ -176,13 +195,20 @@ public class FunctionalList<E> implements Cloneable {
public <T, F> FunctionalList<F> combineWith(
FunctionalList<T> rightList,
BiFunction<E, T, F> itemCombiner) {
+ 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");
+ }
+
FunctionalList<F> returnedList = new FunctionalList<>();
// Get the iterator for the other list
Iterator<T> rightIterator = rightList.toIterable().iterator();
- for (Iterator<E> leftIterator = wrappedList
- .iterator(); leftIterator.hasNext()
+ for (Iterator<E> leftIterator =
+ wrappedList.iterator(); leftIterator.hasNext()
&& rightIterator.hasNext();) {
// Add the transformed items to the result list
E leftVal = leftIterator.next();
@@ -212,6 +238,11 @@ public class FunctionalList<E> implements Cloneable {
* @return The first element in this list.
*/
public E first() {
+ if (wrappedList.size() < 1) {
+ throw new NoSuchElementException(
+ "Attempted to get first element of empty list");
+ }
+
return wrappedList.get(0);
}
@@ -227,14 +258,23 @@ public class FunctionalList<E> implements Cloneable {
* @return A new list containing the flattened results of applying the
* provided function.
*/
- public <T> FunctionalList<T> flatMap(
- Function<E, FunctionalList<T>> elementExpander) {
- FunctionalList<T> returnedList = new FunctionalList<>(
- this.wrappedList.size());
+ public <T> FunctionalList<T>
+ flatMap(Function<E, FunctionalList<T>> elementExpander) {
+ if (elementExpander == null) {
+ throw new NullPointerException("Expander must not be null");
+ }
+
+ FunctionalList<T> returnedList =
+ new FunctionalList<>(this.wrappedList.size());
forEach(element -> {
- FunctionalList<T> expandedElement = elementExpander
- .apply(element);
+ FunctionalList<T> expandedElement =
+ elementExpander.apply(element);
+
+ if (expandedElement == null) {
+ throw new NullPointerException(
+ "Expander returned null list");
+ }
// Add each element to the returned list
expandedElement.forEach(returnedList::add);
@@ -250,6 +290,10 @@ public class FunctionalList<E> implements Cloneable {
* The action to apply to each member of the list.
*/
public void forEach(Consumer<E> action) {
+ if (action == null) {
+ throw new NullPointerException("Action is null");
+ }
+
wrappedList.forEach(action);
}
@@ -261,6 +305,10 @@ public class FunctionalList<E> implements Cloneable {
* index.
*/
public void forEachIndexed(BiConsumer<Integer, E> indexedAction) {
+ if (indexedAction == null) {
+ throw new NullPointerException("Action must not be null");
+ }
+
// This is held b/c ref'd variables must be final/effectively final
GenHolder<Integer> currentIndex = new GenHolder<>(0);
@@ -302,6 +350,10 @@ public class FunctionalList<E> implements Cloneable {
* @return A list containing all elements that match the predicate
*/
public FunctionalList<E> getMatching(Predicate<E> matchPredicate) {
+ if (matchPredicate == null) {
+ throw new NullPointerException("Predicate must not be null");
+ }
+
FunctionalList<E> returnedList = new FunctionalList<>();
wrappedList.forEach((element) -> {
@@ -344,8 +396,12 @@ public class FunctionalList<E> implements Cloneable {
* @return A new list containing the mapped elements of this list.
*/
public <T> FunctionalList<T> map(Function<E, T> elementTransformer) {
- FunctionalList<T> returnedList = new FunctionalList<>(
- this.wrappedList.size());
+ if (elementTransformer == null) {
+ throw new NullPointerException("Transformer must be not null");
+ }
+
+ FunctionalList<T> returnedList =
+ new FunctionalList<>(this.wrappedList.size());
forEach(element -> {
// Add the transformed item to the result
@@ -366,8 +422,8 @@ public class FunctionalList<E> implements Cloneable {
* @return A list containing pairs of this element and the specified
* list
*/
- public <T> FunctionalList<Pair<E, T>> pairWith(
- FunctionalList<T> rightList) {
+ public <T> FunctionalList<Pair<E, T>>
+ pairWith(FunctionalList<T> rightList) {
return combineWith(rightList, Pair<E, T>::new);
}
@@ -378,13 +434,21 @@ public class FunctionalList<E> implements Cloneable {
* The size of elements to put into each one of the sublists
* @return A list partitioned into partitions of size nPerPart
*/
- public FunctionalList<FunctionalList<E>> partition(
- int numberPerPartition) {
- FunctionalList<FunctionalList<E>> returnedList = new FunctionalList<>();
+ public FunctionalList<FunctionalList<E>>
+ partition(int numberPerPartition) {
+ if (numberPerPartition < 1
+ || numberPerPartition > wrappedList.size()) {
+ throw new IllegalArgumentException("" + numberPerPartition
+ + " is an invalid partition size. Must be between 1 and "
+ + wrappedList.size());
+ }
+
+ FunctionalList<FunctionalList<E>> returnedList =
+ new FunctionalList<>();
// The current partition being filled
- GenHolder<FunctionalList<E>> currentPartition = new GenHolder<>(
- new FunctionalList<>());
+ GenHolder<FunctionalList<E>> currentPartition =
+ new GenHolder<>(new FunctionalList<>());
this.forEach((element) -> {
if (isPartitionFull(numberPerPartition, currentPartition)) {
@@ -433,6 +497,11 @@ public class FunctionalList<E> implements Cloneable {
* @return A random element from this list.
*/
public E randItem(Random rnd) {
+ if (rnd == null) {
+ throw new NullPointerException(
+ "Random source must not be null");
+ }
+
int randomIndex = rnd.nextInt(wrappedList.size());
return wrappedList.get(randomIndex);
@@ -460,6 +529,12 @@ public class FunctionalList<E> implements Cloneable {
public <T, F> F reduceAux(T initialValue,
BiFunction<E, T, T> stateAccumulator,
Function<T, F> resultTransformer) {
+ if (stateAccumulator == null) {
+ throw new NullPointerException("Accumulator must not be null");
+ } else if (resultTransformer == null) {
+ throw new NullPointerException("Transformer must not be null");
+ }
+
// The current collapsed list
IHolder<T> currentState = new GenHolder<>(initialValue);
@@ -481,6 +556,10 @@ public class FunctionalList<E> implements Cloneable {
* @return Whether there was anything that satisfied the predicate
*/
public boolean removeIf(Predicate<E> removePredicate) {
+ if (removePredicate == null) {
+ throw new NullPointerException("Predicate must be non-null");
+ }
+
return wrappedList.removeIf(removePredicate);
}
@@ -502,7 +581,8 @@ public class FunctionalList<E> implements Cloneable {
* @param searchKey
* The key to search for.
* @param comparator
- * The way to compare elements for searching
+ * The way to compare elements for searching. Pass null to
+ * use the natural ordering for E
* @return The element if it is in this list, or null if it is not.
*/
public E search(E searchKey, Comparator<E> comparator) {
@@ -524,7 +604,8 @@ public class FunctionalList<E> implements Cloneable {
* elements. Does change the underlying list.
*
* @param comparator
- * The way to compare elements for sorting.
+ * The way to compare elements for sorting. Pass null to use
+ * E's natural ordering
*/
public void sort(Comparator<E> comparator) {
Collections.sort(wrappedList, comparator);
@@ -554,7 +635,7 @@ public class FunctionalList<E> implements Cloneable {
// Remove trailing space and comma
sb.deleteCharAt(sb.length() - 1);
- //sb.deleteCharAt(sb.length() - 2);
+ // sb.deleteCharAt(sb.length() - 2);
sb.append(")");
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java
new file mode 100644
index 0000000..0eb2e94
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java
@@ -0,0 +1,151 @@
+package bjc.utils.funcdata;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+import bjc.utils.data.Pair;
+
+/**
+ * Functional wrapper over map providing some useful things
+ *
+ * @author ben
+ *
+ * @param <K>
+ * The type of this map's keys
+ * @param <V>
+ * The type of this map's values
+ *
+ */
+public class FunctionalMap<K, V> {
+ private final class TransformedMap<V2> extends FunctionalMap<K, V2> {
+ private FunctionalMap<K, V> mapToTransform;
+ private Function<V, V2> transformer;
+
+ public TransformedMap(FunctionalMap<K, V> destMap,
+ Function<V, V2> transform) {
+ mapToTransform = destMap;
+ transformer = transform;
+ }
+
+ @Override
+ public V2 get(K key) {
+ return transformer.apply(mapToTransform.get(key));
+ }
+ }
+
+ private Map<K, V> wrappedMap;
+
+ /**
+ * Create a new blank functional map
+ */
+ public FunctionalMap() {
+ wrappedMap = new HashMap<>();
+ }
+
+ /**
+ * Create a new functional map wrapping the specified map
+ *
+ * @param wrap
+ * The map to wrap
+ */
+ public FunctionalMap(Map<K, V> wrap) {
+ if (wrap == null) {
+ throw new NullPointerException("Map to wrap must not be null");
+ }
+
+ wrappedMap = wrap;
+ }
+
+ /**
+ * Create a new functional map with the specified entries
+ *
+ * @param entries
+ * The entries to put into the map
+ */
+ @SafeVarargs
+ public FunctionalMap(Pair<K, V>... entries) {
+ this();
+
+ for (Pair<K, V> entry : entries) {
+ entry.doWith((key, val) -> {
+ wrappedMap.put(key, val);
+ });
+ }
+ }
+
+ /**
+ * Add an entry to the map
+ *
+ * @param key
+ * The key to put the value under
+ * @param val
+ * The value to add
+ * @return The previous value of the key in the map, or null if the key
+ * wasn't in the map. However, note that it may also return
+ * null if the key was set to null.
+ *
+ */
+ public V put(K key, V val) {
+ if (key == null) {
+ throw new NullPointerException("Key must not be null");
+ }
+
+ return wrappedMap.put(key, val);
+ }
+
+ /**
+ * Get the value assigned to the given key
+ *
+ * @param key
+ * The key to look for a value under
+ * @return The value of the key
+ *
+ *
+ */
+ public V get(K key) {
+ if (key == null) {
+ throw new NullPointerException("Key must not be null");
+ }
+
+ if (wrappedMap.containsKey(wrappedMap)) {
+ return wrappedMap.get(key);
+ } else {
+ throw new IllegalArgumentException(
+ "Key " + key + " is not present in the map");
+ }
+ }
+
+ /**
+ * Transform the values returned by this map.
+ *
+ * NOTE: This transform is applied once for each lookup of a value, so
+ * the transform passed should be a proper function, or things will
+ * likely not work as expected.
+ *
+ * @param <V2>
+ * The new type of returned values
+ * @param transformer
+ * The function to use to transform values
+ * @return The map where each value will be transformed after lookup
+ */
+ public <V2> FunctionalMap<K, V2>
+ mapValues(Function<V, V2> transformer) {
+ if (transformer == null) {
+ throw new NullPointerException("Transformer must not be null");
+ }
+
+ return new TransformedMap<>(this, transformer);
+ }
+
+ /**
+ * Check if this map contains the specified key
+ *
+ * @param key
+ * The key to check
+ * @return Whether or not the map contains the key
+ */
+ public boolean containsKey(K key) {
+ return wrappedMap.containsKey(key);
+ }
+}
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 3c819cd..386b732 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java
@@ -19,6 +19,11 @@ 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");
+ }
+
return new FunctionalStringTokenizer(
new StringTokenizer(strang, " "));
}
@@ -35,6 +40,11 @@ public class FunctionalStringTokenizer {
* The string to tokenize
*/
public FunctionalStringTokenizer(String inp) {
+ if (inp == null) {
+ throw new NullPointerException(
+ "String to tokenize must be non-null");
+ }
+
this.input = new StringTokenizer(inp);
}
@@ -49,6 +59,14 @@ public class FunctionalStringTokenizer {
*/
public FunctionalStringTokenizer(String inputString,
String seperators) {
+ if (inputString == 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");
+ }
+
this.input = new StringTokenizer(inputString, seperators);
}
@@ -59,6 +77,11 @@ 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");
+ }
+
this.input = toWrap;
}
@@ -69,6 +92,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");
+ }
+
while (input.hasMoreTokens()) {
action.accept(input.nextToken());
}
@@ -84,7 +111,7 @@ public class FunctionalStringTokenizer {
}
/**
- * Return the next token from the tokenizer Returns null if no more
+ * Return the next token from the tokenizer. Returns null if no more
* tokens are available
*
* @return The next token from the tokenizer
@@ -110,13 +137,18 @@ public class FunctionalStringTokenizer {
* The function to use to convert tokens.
* @return A list containing all of the converted tokens.
*/
- public <E> FunctionalList<E> toList(Function<String, E> tokenTransformer) {
+ public <E> FunctionalList<E>
+ toList(Function<String, E> tokenTransformer) {
+ if (tokenTransformer == null) {
+ throw new NullPointerException("Transformer must not be null");
+ }
+
FunctionalList<E> returnList = new FunctionalList<>();
// Add each token to the list after transforming it
forEachToken(token -> {
E transformedToken = tokenTransformer.apply(token);
-
+
returnList.add(transformedToken);
});
@@ -124,6 +156,15 @@ public class FunctionalStringTokenizer {
}
/**
+ * Convert this tokenizer into a list of strings
+ *
+ * @return This tokenizer, converted into a list of strings
+ */
+ public FunctionalList<String> toList() {
+ return toList((String element) -> element);
+ }
+
+ /**
* Check if this tokenizer has more tokens
*
* @return Whether or not this tokenizer has more tokens
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 ec0e4df..fa92f85 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,6 +39,10 @@ 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");
+ }
+
elementCount = 0;
comparator = cmp;
}
@@ -169,6 +173,13 @@ public class BinarySearchTree<T> {
*/
public void traverse(TreeLinearizationMethod linearizationMethod,
Predicate<T> traversalPredicate) {
+ if (linearizationMethod == null) {
+ throw new NullPointerException(
+ "Linearization method must not be null");
+ } else if (traversalPredicate == null) {
+ throw new NullPointerException("Predicate must not be nulls");
+ }
+
rootElement.forEach(linearizationMethod, traversalPredicate);
}
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 7e31328..d2f9013 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
@@ -55,6 +55,10 @@ 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");
+ }
+
return leafTransformer.apply(data);
}
@@ -101,6 +105,10 @@ public class BinarySearchTreeLeaf<T> implements ITreePart<T> {
*/
@Override
public boolean directedWalk(DirectedWalkFunction<T> treeWalker) {
+ if (treeWalker == null) {
+ throw new NullPointerException("Tree walker must not be null");
+ }
+
switch (treeWalker.walk(data)) {
case SUCCESS:
return true;
@@ -119,6 +127,10 @@ 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");
+ }
+
return traversalPredicate.test(data);
}
}
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 77bb196..09a4912 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
@@ -51,6 +51,10 @@ 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");
+ }
+
switch (comparator.compare(data, element)) {
case -1:
if (leftBranch == null) {
@@ -79,6 +83,10 @@ 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) {
+ throw new NullPointerException("Collapser must not be null");
+ }
+
E collapsedNode = nodeCollapser.apply(data);
if (leftBranch != null) {
@@ -112,6 +120,10 @@ 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");
+ }
+
return directedWalk(currentElement -> {
switch (comparator.compare(element, currentElement)) {
case -1:
@@ -128,6 +140,10 @@ 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");
+ }
+
directedWalk(currentElement -> {
switch (comparator.compare(data, element)) {
case -1:
@@ -145,6 +161,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");
+ }
+
switch (treeWalker.walk(data)) {
case SUCCESS:
return true;
@@ -162,6 +182,13 @@ public class BinarySearchTreeNode<T> extends BinarySearchTreeLeaf<T> {
@Override
public boolean forEach(TreeLinearizationMethod linearizationMethod,
Predicate<T> traversalPredicate) {
+ if (linearizationMethod == null) {
+ throw new NullPointerException(
+ "Linearization method must not be null");
+ } else if (traversalPredicate == null) {
+ throw new NullPointerException("Predicate must not be null");
+ }
+
switch (linearizationMethod) {
case PREORDER:
return preorderTraverse(linearizationMethod,