From 1c8bc7132d980c1ff2dbd6b9af579c3b2fd8c63e Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Sun, 3 Apr 2016 19:22:48 -0400 Subject: General code refactoring and maintenance --- .../java/bjc/utils/funcdata/FunctionalList.java | 123 +++++++++++++++++---- 1 file changed, 102 insertions(+), 21 deletions(-) (limited to 'BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java') 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 implements Cloneable { * The source for a backing list */ public FunctionalList(FunctionalList 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 implements Cloneable { * The list to use as a backing list. */ public FunctionalList(List backingList) { + if (backingList == null) { + throw new NullPointerException( + "Backing list must be non-null"); + } + wrappedList = backingList; } @@ -112,6 +123,10 @@ public class FunctionalList implements Cloneable { * predicate. */ public boolean allMatch(Predicate 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 implements Cloneable { * predicate. */ public boolean anyMatch(Predicate 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 implements Cloneable { public FunctionalList combineWith( FunctionalList rightList, BiFunction 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 returnedList = new FunctionalList<>(); // Get the iterator for the other list Iterator rightIterator = rightList.toIterable().iterator(); - for (Iterator leftIterator = wrappedList - .iterator(); leftIterator.hasNext() + for (Iterator 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 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 implements Cloneable { * @return A new list containing the flattened results of applying the * provided function. */ - public FunctionalList flatMap( - Function> elementExpander) { - FunctionalList returnedList = new FunctionalList<>( - this.wrappedList.size()); + public FunctionalList + flatMap(Function> elementExpander) { + if (elementExpander == null) { + throw new NullPointerException("Expander must not be null"); + } + + FunctionalList returnedList = + new FunctionalList<>(this.wrappedList.size()); forEach(element -> { - FunctionalList expandedElement = elementExpander - .apply(element); + FunctionalList 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 implements Cloneable { * The action to apply to each member of the list. */ public void forEach(Consumer action) { + if (action == null) { + throw new NullPointerException("Action is null"); + } + wrappedList.forEach(action); } @@ -261,6 +305,10 @@ public class FunctionalList implements Cloneable { * index. */ public void forEachIndexed(BiConsumer 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 currentIndex = new GenHolder<>(0); @@ -302,6 +350,10 @@ public class FunctionalList implements Cloneable { * @return A list containing all elements that match the predicate */ public FunctionalList getMatching(Predicate matchPredicate) { + if (matchPredicate == null) { + throw new NullPointerException("Predicate must not be null"); + } + FunctionalList returnedList = new FunctionalList<>(); wrappedList.forEach((element) -> { @@ -344,8 +396,12 @@ public class FunctionalList implements Cloneable { * @return A new list containing the mapped elements of this list. */ public FunctionalList map(Function elementTransformer) { - FunctionalList returnedList = new FunctionalList<>( - this.wrappedList.size()); + if (elementTransformer == null) { + throw new NullPointerException("Transformer must be not null"); + } + + FunctionalList returnedList = + new FunctionalList<>(this.wrappedList.size()); forEach(element -> { // Add the transformed item to the result @@ -366,8 +422,8 @@ public class FunctionalList implements Cloneable { * @return A list containing pairs of this element and the specified * list */ - public FunctionalList> pairWith( - FunctionalList rightList) { + public FunctionalList> + pairWith(FunctionalList rightList) { return combineWith(rightList, Pair::new); } @@ -378,13 +434,21 @@ public class FunctionalList 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> partition( - int numberPerPartition) { - FunctionalList> returnedList = new FunctionalList<>(); + public FunctionalList> + 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> returnedList = + new FunctionalList<>(); // The current partition being filled - GenHolder> currentPartition = new GenHolder<>( - new FunctionalList<>()); + GenHolder> currentPartition = + new GenHolder<>(new FunctionalList<>()); this.forEach((element) -> { if (isPartitionFull(numberPerPartition, currentPartition)) { @@ -433,6 +497,11 @@ public class FunctionalList 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 implements Cloneable { public F reduceAux(T initialValue, BiFunction stateAccumulator, Function 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 currentState = new GenHolder<>(initialValue); @@ -481,6 +556,10 @@ public class FunctionalList implements Cloneable { * @return Whether there was anything that satisfied the predicate */ public boolean removeIf(Predicate removePredicate) { + if (removePredicate == null) { + throw new NullPointerException("Predicate must be non-null"); + } + return wrappedList.removeIf(removePredicate); } @@ -502,7 +581,8 @@ public class FunctionalList 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 comparator) { @@ -524,7 +604,8 @@ public class FunctionalList 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 comparator) { Collections.sort(wrappedList, comparator); @@ -554,7 +635,7 @@ public class FunctionalList implements Cloneable { // Remove trailing space and comma sb.deleteCharAt(sb.length() - 1); - //sb.deleteCharAt(sb.length() - 2); + // sb.deleteCharAt(sb.length() - 2); sb.append(")"); -- cgit v1.2.3