summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/funcdata
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2016-04-08 13:28:09 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2016-04-08 13:28:09 -0400
commit275a627719fc2231b16caea41130ff09f0f2b6a1 (patch)
tree757e8ca2061ba6ed9b2063f7155edbe954b72bdb /BJC-Utils2/src/main/java/bjc/utils/funcdata
parent79d3a4a47cbc1fcf17c77c6fc12ff826a3077bac (diff)
Switch functional data to use interfaces
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/funcdata')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java316
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java147
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java6
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java281
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalMap.java104
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java5
6 files changed, 587 insertions, 272 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 c680879..9574376 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java
@@ -14,6 +14,7 @@ import java.util.function.Predicate;
import bjc.utils.data.GenHolder;
import bjc.utils.data.IHolder;
+import bjc.utils.data.IPair;
import bjc.utils.data.Pair;
import java.util.ArrayList;
@@ -28,7 +29,7 @@ import java.util.ArrayList;
* @param <E>
* The type in this list
*/
-public class FunctionalList<E> implements Cloneable {
+public class FunctionalList<E> implements Cloneable, IFunctionalList<E> {
/**
* The list used as a backing store
*/
@@ -57,27 +58,6 @@ public class FunctionalList<E> implements Cloneable {
}
/**
- * Create a functional list using the same backing list as the provided
- * list.
- *
- * @param sourceList
- * 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.
- //
- // I've decided it shouldn't. Call clone() if that's what you want.
- // This method just creates another list that refers to the
- // source's backing list
- wrappedList = sourceList.wrappedList;
- }
-
- /**
* Create a new functional list with the specified size.
*
* @param size
@@ -102,26 +82,18 @@ public class FunctionalList<E> implements Cloneable {
wrappedList = backingList;
}
- /**
- * Add an item to this list
- *
- * @param item
- * The item to add to this list.
- * @return Whether the item was added to the list succesfully.
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#add(E)
*/
+ @Override
public boolean add(E item) {
return wrappedList.add(item);
}
- /**
- * Check if all of the elements of this list match the specified
- * predicate.
- *
- * @param matchPredicate
- * The predicate to use for checking.
- * @return Whether all of the elements of the list match the specified
- * predicate.
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#allMatch(java.util.function.Predicate)
*/
+ @Override
public boolean allMatch(Predicate<E> matchPredicate) {
if (matchPredicate == null) {
throw new NullPointerException("Predicate must be non-null");
@@ -138,14 +110,10 @@ public class FunctionalList<E> implements Cloneable {
return true;
}
- /**
- * Check if any of the elements in this list match the specified list.
- *
- * @param matchPredicate
- * The predicate to use for checking.
- * @return Whether any element in the list matches the provided
- * predicate.
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#anyMatch(java.util.function.Predicate)
*/
+ @Override
public boolean anyMatch(Predicate<E> matchPredicate) {
if (matchPredicate == null) {
throw new NullPointerException("Predicate must be not null");
@@ -163,8 +131,8 @@ public class FunctionalList<E> implements Cloneable {
}
@Override
- public FunctionalList<E> clone() {
- FunctionalList<E> clonedList = new FunctionalList<>();
+ public IFunctionalList<E> clone() {
+ IFunctionalList<E> clonedList = new FunctionalList<>();
for (E element : wrappedList) {
clonedList.add(element);
@@ -173,27 +141,12 @@ public class FunctionalList<E> implements Cloneable {
return clonedList;
}
- /**
- * Combine this list with another one into a new list and merge the
- * results. Works sort of like a combined zip/map over resulting pairs.
- * Does not change the underlying list.
- *
- * NOTE: The returned list will have the length of the shorter of this
- * list and the combined one.
- *
- * @param <T>
- * The type of the second list
- * @param <F>
- * The type of the combined list
- *
- * @param rightList
- * The list to combine with
- * @param itemCombiner
- * The function to use for combining element pairs.
- * @return A new list containing the merged pairs of lists.
- */
- public <T, F> FunctionalList<F> combineWith(
- FunctionalList<T> rightList,
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#combineWith(bjc.utils.funcdata.IFunctionalList, java.util.function.BiFunction)
+ */
+ @Override
+ public <T, F> IFunctionalList<F> combineWith(
+ IFunctionalList<T> rightList,
BiFunction<E, T, F> itemCombiner) {
if (rightList == null) {
throw new NullPointerException(
@@ -202,7 +155,7 @@ public class FunctionalList<E> implements Cloneable {
throw new NullPointerException("Combiner must not be null");
}
- FunctionalList<F> returnedList = new FunctionalList<>();
+ IFunctionalList<F> returnedList = new FunctionalList<>();
// Get the iterator for the other list
Iterator<T> rightIterator = rightList.toIterable().iterator();
@@ -220,23 +173,19 @@ public class FunctionalList<E> implements Cloneable {
return returnedList;
}
- /**
- * Check if the list contains the specified item
- *
- * @param item
- * The item to see if it is contained
- * @return Whether or not the specified item is in the list
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#contains(E)
*/
+ @Override
public boolean contains(E item) {
// Check if any items in the list match the provided item
return this.anyMatch(item::equals);
}
- /**
- * Get the first element in the list
- *
- * @return The first element in this list.
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#first()
*/
+ @Override
public E first() {
if (wrappedList.size() < 1) {
throw new NoSuchElementException(
@@ -246,29 +195,21 @@ public class FunctionalList<E> implements Cloneable {
return wrappedList.get(0);
}
- /**
- * Apply a function to each member of the list, then flatten the
- * results. Does not change the underlying list.
- *
- * @param <T>
- * The type of the flattened list
- *
- * @param elementExpander
- * The function to apply to each member of the list.
- * @return A new list containing the flattened results of applying the
- * provided function.
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#flatMap(java.util.function.Function)
*/
- public <T> FunctionalList<T> flatMap(
- Function<E, FunctionalList<T>> elementExpander) {
+ @Override
+ public <T> IFunctionalList<T> flatMap(
+ Function<E, IFunctionalList<T>> elementExpander) {
if (elementExpander == null) {
throw new NullPointerException("Expander must not be null");
}
- FunctionalList<T> returnedList = new FunctionalList<>(
+ IFunctionalList<T> returnedList = new FunctionalList<>(
this.wrappedList.size());
forEach(element -> {
- FunctionalList<T> expandedElement = elementExpander
+ IFunctionalList<T> expandedElement = elementExpander
.apply(element);
if (expandedElement == null) {
@@ -283,12 +224,10 @@ public class FunctionalList<E> implements Cloneable {
return returnedList;
}
- /**
- * Apply a given action for each member of the list
- *
- * @param action
- * The action to apply to each member of the list.
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#forEach(java.util.function.Consumer)
*/
+ @Override
public void forEach(Consumer<E> action) {
if (action == null) {
throw new NullPointerException("Action is null");
@@ -297,13 +236,10 @@ public class FunctionalList<E> implements Cloneable {
wrappedList.forEach(action);
}
- /**
- * Apply a given function to each element in the list and its index.
- *
- * @param indexedAction
- * The function to apply to each element in the list and its
- * index.
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#forEachIndexed(java.util.function.BiConsumer)
*/
+ @Override
public void forEachIndexed(BiConsumer<Integer, E> indexedAction) {
if (indexedAction == null) {
throw new NullPointerException("Action must not be null");
@@ -322,13 +258,10 @@ public class FunctionalList<E> implements Cloneable {
});
}
- /**
- * Retrieve a value in the list by its index.
- *
- * @param index
- * The index to retrieve a value from.
- * @return The value at the specified index in the list.
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#getByIndex(int)
*/
+ @Override
public E getByIndex(int index) {
return wrappedList.get(index);
}
@@ -342,19 +275,16 @@ public class FunctionalList<E> implements Cloneable {
return wrappedList;
}
- /**
- * Retrieve a list containing all elements matching a predicate
- *
- * @param matchPredicate
- * The predicate to match by
- * @return A list containing all elements that match the predicate
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#getMatching(java.util.function.Predicate)
*/
- public FunctionalList<E> getMatching(Predicate<E> matchPredicate) {
+ @Override
+ public IFunctionalList<E> getMatching(Predicate<E> matchPredicate) {
if (matchPredicate == null) {
throw new NullPointerException("Predicate must not be null");
}
- FunctionalList<E> returnedList = new FunctionalList<>();
+ IFunctionalList<E> returnedList = new FunctionalList<>();
wrappedList.forEach((element) -> {
if (matchPredicate.test(element)) {
@@ -366,41 +296,32 @@ public class FunctionalList<E> implements Cloneable {
return returnedList;
}
- /**
- * Retrieve the size of the wrapped list
- *
- * @return The size of the wrapped list
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#getSize()
*/
+ @Override
public int getSize() {
return wrappedList.size();
}
- /**
- * Check if this list is empty.
- *
- * @return Whether or not this list is empty.
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#isEmpty()
*/
+ @Override
public boolean isEmpty() {
return wrappedList.isEmpty();
}
- /**
- * Create a new list by applying the given function to each element in
- * the list. Does not change the underlying list.
- *
- * @param <T>
- * The type of the transformed list
- *
- * @param elementTransformer
- * The function to apply to each element in the list
- * @return A new list containing the mapped elements of this list.
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#map(java.util.function.Function)
*/
- public <T> FunctionalList<T> map(Function<E, T> elementTransformer) {
+ @Override
+ public <T> IFunctionalList<T> map(Function<E, T> elementTransformer) {
if (elementTransformer == null) {
throw new NullPointerException("Transformer must be not null");
}
- FunctionalList<T> returnedList = new FunctionalList<>(
+ IFunctionalList<T> returnedList = new FunctionalList<>(
this.wrappedList.size());
forEach(element -> {
@@ -411,30 +332,20 @@ public class FunctionalList<E> implements Cloneable {
return returnedList;
}
- /**
- * Zip two lists into a list of pairs
- *
- * @param <T>
- * The type of the second list
- *
- * @param rightList
- * The list to use as the left side of the pair
- * @return A list containing pairs of this element and the specified
- * list
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#pairWith(bjc.utils.funcdata.IFunctionalList)
*/
- public <T> FunctionalList<Pair<E, T>> pairWith(
- FunctionalList<T> rightList) {
+ @Override
+ public <T> IFunctionalList<IPair<E, T>> pairWith(
+ IFunctionalList<T> rightList) {
return combineWith(rightList, Pair<E, T>::new);
}
- /**
- * Partition this list into a list of sublists
- *
- * @param numberPerPartition
- * The size of elements to put into each one of the sublists
- * @return A list partitioned into partitions of size nPerPart
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#partition(int)
*/
- public FunctionalList<FunctionalList<E>> partition(
+ @Override
+ public IFunctionalList<IFunctionalList<E>> partition(
int numberPerPartition) {
if (numberPerPartition < 1
|| numberPerPartition > wrappedList.size()) {
@@ -443,10 +354,10 @@ public class FunctionalList<E> implements Cloneable {
+ wrappedList.size());
}
- FunctionalList<FunctionalList<E>> returnedList = new FunctionalList<>();
+ IFunctionalList<IFunctionalList<E>> returnedList = new FunctionalList<>();
// The current partition being filled
- GenHolder<FunctionalList<E>> currentPartition = new GenHolder<>(
+ GenHolder<IFunctionalList<E>> currentPartition = new GenHolder<>(
new FunctionalList<>());
this.forEach((element) -> {
@@ -472,29 +383,23 @@ public class FunctionalList<E> implements Cloneable {
* Check if a partition has room for another item
*/
private Boolean isPartitionFull(int numberPerPartition,
- GenHolder<FunctionalList<E>> currentPartition) {
+ GenHolder<IFunctionalList<E>> currentPartition) {
return currentPartition.unwrap(
(partition) -> partition.getSize() >= numberPerPartition);
}
- /**
- * Prepend an item to the list
- *
- * @param item
- * The item to prepend to the list
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#prepend(E)
*/
+ @Override
public void prepend(E item) {
wrappedList.add(0, item);
}
- /**
- * Select a random item from this list, using the provided random
- * number generator.
- *
- * @param rnd
- * The random number generator to use.
- * @return A random element from this list.
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#randItem(java.util.Random)
*/
+ @Override
public E randItem(Random rnd) {
if (rnd == null) {
throw new NullPointerException(
@@ -506,25 +411,10 @@ public class FunctionalList<E> implements Cloneable {
return wrappedList.get(randomIndex);
}
- /**
- * Reduce this list to a single value, using a accumulative approach.
- *
- * @param <T>
- * The in-between type of the values
- * @param <F>
- * The final value type
- *
- * @param initialValue
- * The initial value of the accumulative state.
- * @param stateAccumulator
- * The function to use to combine a list element with the
- * accumulative state.
- * @param resultTransformer
- * The function to use to convert the accumulative state
- * into a final result.
- * @return A single value condensed from this list and transformed into
- * its final state.
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#reduceAux(T, java.util.function.BiFunction, java.util.function.Function)
*/
+ @Override
public <T, F> F reduceAux(T initialValue,
BiFunction<E, T, T> stateAccumulator,
Function<T, F> resultTransformer) {
@@ -547,13 +437,10 @@ public class FunctionalList<E> implements Cloneable {
return currentState.unwrap(resultTransformer);
}
- /**
- * Remove all elements that match a given predicate
- *
- * @param removePredicate
- * The predicate to use to determine elements to delete
- * @return Whether there was anything that satisfied the predicate
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#removeIf(java.util.function.Predicate)
*/
+ @Override
public boolean removeIf(Predicate<E> removePredicate) {
if (removePredicate == null) {
throw new NullPointerException("Predicate must be non-null");
@@ -562,28 +449,18 @@ public class FunctionalList<E> implements Cloneable {
return wrappedList.removeIf(removePredicate);
}
- /**
- * Remove all parameters that match a given parameter
- *
- * @param desiredElement
- * The object to remove all matching copies of
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#removeMatching(E)
*/
+ @Override
public void removeMatching(E desiredElement) {
removeIf((element) -> element.equals(desiredElement));
}
- /**
- * Perform a binary search for the specified key using the provided
- * means of comparing elements. Since this IS a binary search, the list
- * must have been sorted before hand.
- *
- * @param searchKey
- * The key to search for.
- * @param comparator
- * 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.
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#search(E, java.util.Comparator)
*/
+ @Override
public E search(E searchKey, Comparator<E> comparator) {
// Search our internal list
int foundIndex = Collections.binarySearch(wrappedList, searchKey,
@@ -598,23 +475,18 @@ public class FunctionalList<E> implements Cloneable {
return null;
}
- /**
- * Sort the elements of this list using the provided way of comparing
- * elements. Does change the underlying list.
- *
- * @param comparator
- * The way to compare elements for sorting. Pass null to use
- * E's natural ordering
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#sort(java.util.Comparator)
*/
+ @Override
public void sort(Comparator<E> comparator) {
Collections.sort(wrappedList, comparator);
}
- /**
- * Convert the list into a iterable
- *
- * @return An iterable view onto the list
+ /* (non-Javadoc)
+ * @see bjc.utils.funcdata.IFunctionalList#toIterable()
*/
+ @Override
public Iterable<E> toIterable() {
return wrappedList;
}
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 0453988..fc4c4de 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java
@@ -2,27 +2,40 @@ package bjc.utils.funcdata;
import java.util.HashMap;
import java.util.Map;
+import java.util.function.BiConsumer;
import java.util.function.Function;
import bjc.utils.data.Pair;
/**
- * Functional wrapper over map providing some useful things
+ * Basic implementation of {@link IFunctionalMap}
*
* @author ben
- *
+ *
* @param <K>
- * The type of this map's keys
+ * The type of the map's keys
* @param <V>
- * The type of this map's values
- *
+ * The type of the 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 class FunctionalMap<K, V> implements IFunctionalMap<K, V> {
+ /**
+ * A map that transforms values from one type to another
+ *
+ * @author ben
+ *
+ * @param <K>
+ * The type of the map's keys
+ * @param <V>
+ * The type of the map's values
+ * @param <V2>
+ * The type of the transformed values
+ */
+ private static final class TransformedValueMap<K, V, V2>
+ implements IFunctionalMap<K, V2> {
+ private IFunctionalMap<K, V> mapToTransform;
+ private Function<V, V2> transformer;
- public TransformedMap(FunctionalMap<K, V> destMap,
+ public TransformedValueMap(IFunctionalMap<K, V> destMap,
Function<V, V2> transform) {
mapToTransform = destMap;
transformer = transform;
@@ -42,6 +55,40 @@ public class FunctionalMap<K, V> {
public String toString() {
return mapToTransform.toString();
}
+
+ @Override
+ public V2 put(K key, V2 val) {
+ throw new UnsupportedOperationException(
+ "Can't add items to transformed map");
+ }
+
+ @Override
+ public <V3> IFunctionalMap<K, V3> mapValues(
+ Function<V2, V3> transform) {
+ return new TransformedValueMap<>(this, transform);
+ }
+
+ @Override
+ public IFunctionalList<K> keyList() {
+ return mapToTransform.keyList();
+ }
+
+ @Override
+ public void forEach(BiConsumer<K, V2> action) {
+ mapToTransform.forEach((key, val) -> {
+ action.accept(key, transformer.apply(val));
+ });
+ }
+
+ @Override
+ public V2 remove(K key) {
+ return transformer.apply(mapToTransform.remove(key));
+ }
+
+ @Override
+ public int getSize() {
+ return mapToTransform.getSize();
+ }
}
private Map<K, V> wrappedMap;
@@ -84,18 +131,12 @@ public class FunctionalMap<K, V> {
}
}
- /**
- * 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.
+ /*
+ * (non-Javadoc)
*
+ * @see bjc.utils.funcdata.IFunctionalMap#put(K, V)
*/
+ @Override
public V put(K key, V val) {
if (key == null) {
throw new NullPointerException("Key must not be null");
@@ -104,15 +145,12 @@ public class FunctionalMap<K, V> {
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
- *
+ /*
+ * (non-Javadoc)
*
+ * @see bjc.utils.funcdata.IFunctionalMap#get(K)
*/
+ @Override
public V get(K key) {
if (key == null) {
throw new NullPointerException("Key must not be null");
@@ -126,35 +164,28 @@ public class FunctionalMap<K, V> {
return wrappedMap.get(key);
}
- /**
- * Transform the values returned by this map.
+ /*
+ * (non-Javadoc)
*
- * 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
+ * @see bjc.utils.funcdata.IFunctionalMap#mapValues(java.util.function.
+ * Function)
*/
- public <V2> FunctionalMap<K, V2> mapValues(
+ @Override
+ public <V2> IFunctionalMap<K, V2> mapValues(
Function<V, V2> transformer) {
if (transformer == null) {
throw new NullPointerException("Transformer must not be null");
}
- return new TransformedMap<>(this, transformer);
+ return new TransformedValueMap<>(this, transformer);
}
- /**
- * Check if this map contains the specified key
+ /*
+ * (non-Javadoc)
*
- * @param key
- * The key to check
- * @return Whether or not the map contains the key
+ * @see bjc.utils.funcdata.IFunctionalMap#containsKey(K)
*/
+ @Override
public boolean containsKey(K key) {
return wrappedMap.containsKey(key);
}
@@ -163,4 +194,30 @@ public class FunctionalMap<K, V> {
public String toString() {
return wrappedMap.toString();
}
+
+ @Override
+ public IFunctionalList<K> keyList() {
+ FunctionalList<K> keys = new FunctionalList<>();
+
+ wrappedMap.keySet().forEach((key) -> {
+ keys.add(key);
+ });
+
+ return keys;
+ }
+
+ @Override
+ public void forEach(BiConsumer<K, V> action) {
+ wrappedMap.forEach(action);
+ }
+
+ @Override
+ public V remove(K key) {
+ return wrappedMap.remove(key);
+ }
+
+ @Override
+ public int getSize() {
+ return wrappedMap.size();
+ }
} \ No newline at end of file
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 9ef59fb..0e2d199 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java
@@ -137,13 +137,13 @@ public class FunctionalStringTokenizer {
* The function to use to convert tokens.
* @return A list containing all of the converted tokens.
*/
- public <E> FunctionalList<E> toList(
+ public <E> IFunctionalList<E> toList(
Function<String, E> tokenTransformer) {
if (tokenTransformer == null) {
throw new NullPointerException("Transformer must not be null");
}
- FunctionalList<E> returnList = new FunctionalList<>();
+ IFunctionalList<E> returnList = new FunctionalList<>();
// Add each token to the list after transforming it
forEachToken(token -> {
@@ -160,7 +160,7 @@ public class FunctionalStringTokenizer {
*
* @return This tokenizer, converted into a list of strings
*/
- public FunctionalList<String> toList() {
+ public IFunctionalList<String> toList() {
return toList((String element) -> element);
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java
new file mode 100644
index 0000000..a017aa9
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java
@@ -0,0 +1,281 @@
+package bjc.utils.funcdata;
+
+import java.util.Comparator;
+import java.util.Random;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import bjc.utils.data.IPair;
+
+/**
+ * A wrapper over another list that provides eager functional operations
+ * over it. Differs from a stream in every way except for the fact that
+ * they both provide functional operations.
+ *
+ * @author ben
+ *
+ * @param <E>
+ * The type in this list
+ */
+public interface IFunctionalList<E> {
+
+ /**
+ * Add an item to this list
+ *
+ * @param item
+ * The item to add to this list.
+ * @return Whether the item was added to the list succesfully.
+ */
+ boolean add(E item);
+
+ /**
+ * Check if all of the elements of this list match the specified
+ * predicate.
+ *
+ * @param matchPredicate
+ * The predicate to use for checking.
+ * @return Whether all of the elements of the list match the specified
+ * predicate.
+ */
+ boolean allMatch(Predicate<E> matchPredicate);
+
+ /**
+ * Check if any of the elements in this list match the specified list.
+ *
+ * @param matchPredicate
+ * The predicate to use for checking.
+ * @return Whether any element in the list matches the provided
+ * predicate.
+ */
+ boolean anyMatch(Predicate<E> matchPredicate);
+
+ /**
+ * Combine this list with another one into a new list and merge the
+ * results. Works sort of like a combined zip/map over resulting pairs.
+ * Does not change the underlying list.
+ *
+ * NOTE: The returned list will have the length of the shorter of this
+ * list and the combined one.
+ *
+ * @param <T>
+ * The type of the second list
+ * @param <F>
+ * The type of the combined list
+ *
+ * @param rightList
+ * The list to combine with
+ * @param itemCombiner
+ * The function to use for combining element pairs.
+ * @return A new list containing the merged pairs of lists.
+ */
+ <T, F> IFunctionalList<F> combineWith(IFunctionalList<T> rightList,
+ BiFunction<E, T, F> itemCombiner);
+
+ /**
+ * Check if the list contains the specified item
+ *
+ * @param item
+ * The item to see if it is contained
+ * @return Whether or not the specified item is in the list
+ */
+ boolean contains(E item);
+
+ /**
+ * Get the first element in the list
+ *
+ * @return The first element in this list.
+ */
+ E first();
+
+ /**
+ * Apply a function to each member of the list, then flatten the
+ * results. Does not change the underlying list.
+ *
+ * @param <T>
+ * The type of the flattened list
+ *
+ * @param elementExpander
+ * The function to apply to each member of the list.
+ * @return A new list containing the flattened results of applying the
+ * provided function.
+ */
+ <T> IFunctionalList<T> flatMap(
+ Function<E, IFunctionalList<T>> elementExpander);
+
+ /**
+ * Apply a given action for each member of the list
+ *
+ * @param action
+ * The action to apply to each member of the list.
+ */
+ void forEach(Consumer<E> action);
+
+ /**
+ * Apply a given function to each element in the list and its index.
+ *
+ * @param indexedAction
+ * The function to apply to each element in the list and its
+ * index.
+ */
+ void forEachIndexed(BiConsumer<Integer, E> indexedAction);
+
+ /**
+ * Retrieve a value in the list by its index.
+ *
+ * @param index
+ * The index to retrieve a value from.
+ * @return The value at the specified index in the list.
+ */
+ E getByIndex(int index);
+
+ /**
+ * Retrieve a list containing all elements matching a predicate
+ *
+ * @param matchPredicate
+ * The predicate to match by
+ * @return A list containing all elements that match the predicate
+ */
+ IFunctionalList<E> getMatching(Predicate<E> matchPredicate);
+
+ /**
+ * Retrieve the size of the wrapped list
+ *
+ * @return The size of the wrapped list
+ */
+ int getSize();
+
+ /**
+ * Check if this list is empty.
+ *
+ * @return Whether or not this list is empty.
+ */
+ boolean isEmpty();
+
+ /**
+ * Create a new list by applying the given function to each element in
+ * the list. Does not change the underlying list.
+ *
+ * @param <T>
+ * The type of the transformed list
+ *
+ * @param elementTransformer
+ * The function to apply to each element in the list
+ * @return A new list containing the mapped elements of this list.
+ */
+ <T> IFunctionalList<T> map(Function<E, T> elementTransformer);
+
+ /**
+ * Zip two lists into a list of pairs
+ *
+ * @param <T>
+ * The type of the second list
+ *
+ * @param rightList
+ * The list to use as the left side of the pair
+ * @return A list containing pairs of this element and the specified
+ * list
+ */
+ <T> IFunctionalList<IPair<E, T>> pairWith(
+ IFunctionalList<T> rightList);
+
+ /**
+ * Partition this list into a list of sublists
+ *
+ * @param numberPerPartition
+ * The size of elements to put into each one of the sublists
+ * @return A list partitioned into partitions of size nPerPart
+ */
+ IFunctionalList<IFunctionalList<E>> partition(int numberPerPartition);
+
+ /**
+ * Prepend an item to the list
+ *
+ * @param item
+ * The item to prepend to the list
+ */
+ void prepend(E item);
+
+ /**
+ * Select a random item from this list, using the provided random
+ * number generator.
+ *
+ * @param rnd
+ * The random number generator to use.
+ * @return A random element from this list.
+ */
+ E randItem(Random rnd);
+
+ /**
+ * Reduce this list to a single value, using a accumulative approach.
+ *
+ * @param <T>
+ * The in-between type of the values
+ * @param <F>
+ * The final value type
+ *
+ * @param initialValue
+ * The initial value of the accumulative state.
+ * @param stateAccumulator
+ * The function to use to combine a list element with the
+ * accumulative state.
+ * @param resultTransformer
+ * The function to use to convert the accumulative state
+ * into a final result.
+ * @return A single value condensed from this list and transformed into
+ * its final state.
+ */
+ <T, F> F reduceAux(T initialValue,
+ BiFunction<E, T, T> stateAccumulator,
+ Function<T, F> resultTransformer);
+
+ /**
+ * Remove all elements that match a given predicate
+ *
+ * @param removePredicate
+ * The predicate to use to determine elements to delete
+ * @return Whether there was anything that satisfied the predicate
+ */
+ boolean removeIf(Predicate<E> removePredicate);
+
+ /**
+ * Remove all parameters that match a given parameter
+ *
+ * @param desiredElement
+ * The object to remove all matching copies of
+ */
+ void removeMatching(E desiredElement);
+
+ /**
+ * Perform a binary search for the specified key using the provided
+ * means of comparing elements. Since this IS a binary search, the list
+ * must have been sorted before hand.
+ *
+ * @param searchKey
+ * The key to search for.
+ * @param comparator
+ * 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.
+ */
+ E search(E searchKey, Comparator<E> comparator);
+
+ /**
+ * Sort the elements of this list using the provided way of comparing
+ * elements. Does change the underlying list.
+ *
+ * @param comparator
+ * The way to compare elements for sorting. Pass null to use
+ * E's natural ordering
+ */
+ void sort(Comparator<E> comparator);
+
+ /**
+ * Convert the list into a iterable
+ *
+ * @return An iterable view onto the list
+ */
+ Iterable<E> toIterable();
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalMap.java
new file mode 100644
index 0000000..9bd62bc
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalMap.java
@@ -0,0 +1,104 @@
+package bjc.utils.funcdata;
+
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
+/**
+ * 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 interface IFunctionalMap<K, V> {
+
+ /**
+ * 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.
+ *
+ * @throws UnsupportedOperationException
+ * if the map implementation doesn't support modifying the
+ * map
+ */
+ V put(K key, V 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
+ *
+ *
+ */
+ V get(K key);
+
+ /**
+ * 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
+ */
+ <V2> IFunctionalMap<K, V2> mapValues(Function<V, V2> transformer);
+
+ /**
+ * Check if this map contains the specified key
+ *
+ * @param key
+ * The key to check
+ * @return Whether or not the map contains the key
+ */
+ boolean containsKey(K key);
+
+ /**
+ * Get a list of all the keys in this map
+ *
+ * @return A list of all the keys in this map
+ */
+ IFunctionalList<K> keyList();
+
+ /**
+ * Execute an action for each entry in the map
+ *
+ * @param action
+ * the action to execute for each entry in the map
+ */
+ void forEach(BiConsumer<K, V> action);
+
+ /**
+ * Remove the value bound to the key
+ *
+ * @param key
+ * The key to remove from the map
+ * @return The previous value for the key in the map, or null if the
+ * key wasn't in the class. NOTE: Just because you recieved
+ * null, doesn't mean the map wasn't changed. It may mean that
+ * someone put a null value for that key into the map
+ */
+ V remove(K key);
+
+ /**
+ * Get the number of entries in this map
+ *
+ * @return The number of entries in this map
+ */
+ int getSize();
+} \ No newline at end of file
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 fa92f85..67b9985 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
@@ -6,6 +6,7 @@ import java.util.List;
import java.util.function.Predicate;
import bjc.utils.funcdata.FunctionalList;
+import bjc.utils.funcdata.IFunctionalList;
import bjc.utils.funcdata.bst.ITreePart.TreeLinearizationMethod;
/**
@@ -68,7 +69,7 @@ public class BinarySearchTree<T> {
* time, but also O(N) space.
*/
public void balance() {
- FunctionalList<T> elements = new FunctionalList<>();
+ IFunctionalList<T> elements = new FunctionalList<>();
// Add each element to the list in sorted order
rootElement.forEach(TreeLinearizationMethod.INORDER,
@@ -123,7 +124,7 @@ public class BinarySearchTree<T> {
* The distance from the pivot
* @return Whether the adjusted pivot is with the list
*/
- private boolean adjustedPivotInBounds(FunctionalList<T> elements,
+ private boolean adjustedPivotInBounds(IFunctionalList<T> elements,
int pivot, int pivotAdjustment) {
return (pivot - pivotAdjustment) >= 0
&& (pivot + pivotAdjustment) < elements.getSize();