diff options
| author | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2017-10-08 22:39:59 -0300 |
|---|---|---|
| committer | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2017-10-08 22:39:59 -0300 |
| commit | c82e3b3b2de0633317ec8fc85925e91422820597 (patch) | |
| tree | 96567416ce23c5ce85601f9cedc3a94bb1c55cba /BJC-Utils2/src/main/java/bjc/utils/funcdata | |
| parent | b3ac1c8690c3e14c879913e5dcc03a5f5e14876e (diff) | |
Start splitting into maven modules
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/funcdata')
16 files changed, 0 insertions, 2606 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 deleted file mode 100644 index 909c5e9..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java +++ /dev/null @@ -1,127 +0,0 @@ -package bjc.utils.funcdata; - -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; - -import bjc.utils.funcutils.ListUtils; - -class ExtendedMap<KeyType, ValueType> implements IMap<KeyType, ValueType> { - private final IMap<KeyType, ValueType> delegate; - - private final IMap<KeyType, ValueType> store; - - public ExtendedMap(final IMap<KeyType, ValueType> delegate, final IMap<KeyType, ValueType> store) { - this.delegate = delegate; - this.store = store; - } - - @Override - public void clear() { - store.clear(); - } - - @Override - public boolean containsKey(final KeyType key) { - if (store.containsKey(key)) return true; - - return delegate.containsKey(key); - } - - @Override - public IMap<KeyType, ValueType> extend() { - return new ExtendedMap<>(this, new FunctionalMap<>()); - } - - @Override - public void forEach(final BiConsumer<KeyType, ValueType> action) { - store.forEach(action); - - delegate.forEach(action); - } - - @Override - public void forEachKey(final Consumer<KeyType> action) { - store.forEachKey(action); - - delegate.forEachKey(action); - } - - @Override - public void forEachValue(final Consumer<ValueType> action) { - store.forEachValue(action); - - delegate.forEachValue(action); - } - - @Override - public ValueType get(final KeyType key) { - if (store.containsKey(key)) return store.get(key); - - return delegate.get(key); - } - - @Override - public int size() { - return store.size() + delegate.size(); - } - - @Override - public IList<KeyType> keyList() { - return ListUtils.mergeLists(store.keyList(), delegate.keyList()); - } - - @Override - public <MappedValue> IMap<KeyType, MappedValue> transform(final Function<ValueType, MappedValue> transformer) { - return new TransformedValueMap<>(this, transformer); - } - - @Override - public ValueType put(final KeyType key, final ValueType val) { - return store.put(key, val); - } - - @Override - public ValueType remove(final KeyType key) { - if (!store.containsKey(key)) return delegate.remove(key); - - return store.remove(key); - } - - @Override - 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(final Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (!(obj instanceof ExtendedMap)) return false; - - final 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 deleted file mode 100644 index 55ea7ff..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java +++ /dev/null @@ -1,423 +0,0 @@ -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.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.IHolder; -import bjc.utils.data.IPair; -import bjc.utils.data.Identity; -import bjc.utils.data.Pair; - -/** - * 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 class FunctionalList<E> implements Cloneable, IList<E> { - /* - * The list used as a backing store - */ - private final List<E> wrapped; - - /** - * Create a new empty functional list. - */ - public FunctionalList() { - wrapped = new ArrayList<>(); - } - - /** - * Create a new functional list containing the specified items. - * - * Takes O(n) time, where n is the number of items specified - * - * @param items - * The items to put into this functional list. - */ - @SafeVarargs - public FunctionalList(final E... items) { - wrapped = new ArrayList<>(items.length); - - for (final E item : items) { - wrapped.add(item); - } - } - - /** - * Create a new functional list with the specified size. - * - * @param size - * The size of the backing list . - */ - private FunctionalList(final int size) { - wrapped = new ArrayList<>(size); - } - - /** - * Create a new functional list as a wrapper of a existing list. - * - * Takes O(1) time, since it doesn't copy the list. - * - * @param backing - * The list to use as a backing list. - */ - public FunctionalList(final List<E> backing) { - if (backing == null) throw new NullPointerException("Backing list must be non-null"); - - wrapped = backing; - } - - @Override - public boolean add(final E item) { - return wrapped.add(item); - } - - @Override - public boolean allMatch(final Predicate<E> predicate) { - if (predicate == null) throw new NullPointerException("Predicate must be non-null"); - - for (final E item : wrapped) { - if (!predicate.test(item)) - // We've found a non-matching item - return false; - } - - // All of the items matched - return true; - } - - @Override - public boolean anyMatch(final Predicate<E> predicate) { - if (predicate == null) throw new NullPointerException("Predicate must be not null"); - - for (final E item : wrapped) { - if (predicate.test(item)) - // We've found a matching item - return true; - } - - // We didn't find a matching item - return false; - } - - /** - * Clone this list into a new one, and clone the backing list as well - * - * Takes O(n) time, where n is the number of elements in the list - * - * @return A list - */ - @Override - public IList<E> clone() { - final IList<E> cloned = new FunctionalList<>(); - - for (final E element : wrapped) { - cloned.add(element); - } - - return cloned; - } - - @Override - public <T, F> IList<F> combineWith(final IList<T> rightList, final 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"); - - final IList<F> returned = new FunctionalList<>(); - - // Get the iterator for the other list - final Iterator<T> rightIterator = rightList.toIterable().iterator(); - - for (final Iterator<E> leftIterator = wrapped.iterator(); leftIterator.hasNext() - && rightIterator.hasNext();) { - // Add the transformed items to the result list - final E leftVal = leftIterator.next(); - final T rightVal = rightIterator.next(); - - returned.add(itemCombiner.apply(leftVal, rightVal)); - } - - return returned; - } - - @Override - public boolean contains(final E item) { - // Check if any items in the list match the provided item - return this.anyMatch(item::equals); - } - - @Override - public E first() { - 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(final Function<E, IList<T>> expander) { - if (expander == null) throw new NullPointerException("Expander must not be null"); - - final IList<T> returned = new FunctionalList<>(this.wrapped.size()); - - forEach(element -> { - final IList<T> expandedElement = expander.apply(element); - - if (expandedElement == null) throw new NullPointerException("Expander returned null list"); - - // Add each element to the returned list - expandedElement.forEach(returned::add); - }); - - return returned; - } - - @Override - public void forEach(final Consumer<? super E> action) { - if (action == null) throw new NullPointerException("Action is null"); - - wrapped.forEach(action); - } - - @Override - public void forEachIndexed(final 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 - final IHolder<Integer> currentIndex = new Identity<>(0); - - wrapped.forEach((element) -> { - // Call the action with the index and the value - indexedAction.accept(currentIndex.unwrap(index -> index), element); - - // Increment the value - currentIndex.transform((index) -> index + 1); - }); - } - - @Override - public E getByIndex(final int index) { - return wrapped.get(index); - } - - /** - * Get the internal backing list. - * - * @return The backing list this list is based off of. - */ - public List<E> getInternal() { - return wrapped; - } - - @Override - public IList<E> getMatching(final Predicate<E> predicate) { - if (predicate == null) throw new NullPointerException("Predicate must not be null"); - - final IList<E> returned = new FunctionalList<>(); - - wrapped.forEach((element) -> { - if (predicate.test(element)) { - // The item matches, so add it to the returned - // list - returned.add(element); - } - }); - - return returned; - } - - @Override - public int getSize() { - return wrapped.size(); - } - - @Override - public boolean isEmpty() { - return wrapped.isEmpty(); - } - - /* - * Check if a partition has room for another item - */ - private Boolean isPartitionFull(final int numberPerPartition, final IHolder<IList<E>> currentPartition) { - return currentPartition.unwrap((partition) -> partition.getSize() >= numberPerPartition); - } - - @Override - public <T> IList<T> map(final Function<E, T> elementTransformer) { - if (elementTransformer == null) throw new NullPointerException("Transformer must be not null"); - - final IList<T> returned = new FunctionalList<>(this.wrapped.size()); - - forEach(element -> { - // Add the transformed item to the result - returned.add(elementTransformer.apply(element)); - }); - - return returned; - } - - @Override - public <T> IList<IPair<E, T>> pairWith(final IList<T> rightList) { - return combineWith(rightList, Pair<E, T>::new); - } - - @Override - public IList<IList<E>> partition(final int numberPerPartition) { - if (numberPerPartition < 1 || numberPerPartition > wrapped.size()) { - final String fmt = "%s is an invalid partition size. Must be between 1 and %d"; - final String msg = String.format(fmt, numberPerPartition, wrapped.size()); - - throw new IllegalArgumentException(msg); - } - - final IList<IList<E>> returned = new FunctionalList<>(); - - // The current partition being filled - final IHolder<IList<E>> currentPartition = new Identity<>(new FunctionalList<>()); - - this.forEach(element -> { - if (isPartitionFull(numberPerPartition, currentPartition)) { - // Add the partition to the list - returned.add(currentPartition.unwrap(partition -> partition)); - - // Start a new partition - currentPartition.transform(partition -> new FunctionalList<>()); - } else { - // Add the element to the current partition - currentPartition.unwrap(partition -> partition.add(element)); - } - }); - - return returned; - } - - @Override - public void prepend(final E item) { - wrapped.add(0, item); - } - - @Override - public E randItem(final Function<Integer, Integer> rnd) { - if (rnd == null) throw new NullPointerException("Random source must not be null"); - - final int randomIndex = rnd.apply(wrapped.size()); - - return wrapped.get(randomIndex); - } - - @Override - public <T, F> F reduceAux(final T initialValue, final BiFunction<E, T, T> stateAccumulator, - final 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 - final IHolder<T> currentState = new Identity<>(initialValue); - - wrapped.forEach(element -> { - // Accumulate a new value into the state - currentState.transform(state -> stateAccumulator.apply(element, state)); - }); - - // Convert the state to its final value - return currentState.unwrap(resultTransformer); - } - - @Override - public boolean removeIf(final Predicate<E> removePredicate) { - if (removePredicate == null) throw new NullPointerException("Predicate must be non-null"); - - return wrapped.removeIf(removePredicate); - } - - @Override - public void removeMatching(final E desiredElement) { - removeIf(element -> element.equals(desiredElement)); - } - - @Override - public void reverse() { - Collections.reverse(wrapped); - } - - @Override - public E search(final E searchKey, final Comparator<E> comparator) { - // Search our internal list - final int foundIndex = Collections.binarySearch(wrapped, searchKey, comparator); - - if (foundIndex >= 0) // We found a matching element - return wrapped.get(foundIndex); - - // We didn't find an element - return null; - } - - @Override - public void sort(final Comparator<E> comparator) { - // sb.deleteCharAt(sb.length() - 2); - Collections.sort(wrapped, comparator); - } - - @Override - public IList<E> tail() { - return new FunctionalList<>(wrapped.subList(1, getSize())); - } - - @Override - public E[] toArray(final E[] arrType) { - return wrapped.toArray(arrType); - } - - @Override - public Iterable<E> toIterable() { - return wrapped; - } - - @Override - public String toString() { - final int lSize = getSize(); - - if (lSize == 0) return "()"; - - final StringBuilder sb = new StringBuilder("("); - final Iterator<E> itr = toIterable().iterator(); - final E itm = itr.next(); - int i = 0; - - if (lSize == 1) return "(" + itm + ")"; - - for (final E item : toIterable()) { - sb.append(item.toString()); - - if (i < lSize - 1) { - sb.append(", "); - } - - i += 1; - } - - 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 deleted file mode 100644 index c4f0ff1..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java +++ /dev/null @@ -1,175 +0,0 @@ -package bjc.utils.funcdata; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; - -import bjc.utils.data.IPair; - -/** - * Basic implementation of {@link IMap} - * - * @author ben - * - * @param <KeyType> - * The type of the map's keys - * @param <ValueType> - * The type of the map's values - */ -public class FunctionalMap<KeyType, ValueType> implements IMap<KeyType, ValueType> { - private Map<KeyType, ValueType> wrappedMap; - - /** - * Create a new blank functional map - */ - public FunctionalMap() { - wrappedMap = new HashMap<>(); - } - - /** - * Create a new functional map with the specified entries - * - * @param entries - * The entries to put into the map - */ - @SafeVarargs - public FunctionalMap(final IPair<KeyType, ValueType>... entries) { - this(); - - for (final IPair<KeyType, ValueType> entry : entries) { - entry.doWith((key, val) -> { - wrappedMap.put(key, val); - }); - } - } - - /** - * Create a new functional map wrapping the specified map - * - * @param wrap - * The map to wrap - */ - public FunctionalMap(final Map<KeyType, ValueType> wrap) { - if (wrap == null) throw new NullPointerException("Map to wrap must not be null"); - - wrappedMap = wrap; - } - - @Override - public void clear() { - wrappedMap.clear(); - } - - @Override - public boolean containsKey(final KeyType key) { - return wrappedMap.containsKey(key); - } - - @Override - public IMap<KeyType, ValueType> extend() { - return new ExtendedMap<>(this, new FunctionalMap<>()); - } - - @Override - public void forEach(final BiConsumer<KeyType, ValueType> action) { - wrappedMap.forEach(action); - } - - @Override - public void forEachKey(final Consumer<KeyType> action) { - wrappedMap.keySet().forEach(action); - } - - @Override - public void forEachValue(final Consumer<ValueType> action) { - wrappedMap.values().forEach(action); - } - - @Override - public ValueType get(final KeyType key) { - if (key == null) throw new NullPointerException("Key must not be null"); - - if (!wrappedMap.containsKey(key)) { - final String msg = String.format("Key %s is not present in the map", key); - - throw new IllegalArgumentException(msg); - } - - return wrappedMap.get(key); - } - - @Override - public int size() { - return wrappedMap.size(); - } - - @Override - public IList<KeyType> keyList() { - final FunctionalList<KeyType> keys = new FunctionalList<>(); - - wrappedMap.keySet().forEach(key -> { - keys.add(key); - }); - - return keys; - } - - @Override - public <MappedValue> IMap<KeyType, MappedValue> transform(final Function<ValueType, MappedValue> transformer) { - if (transformer == null) throw new NullPointerException("Transformer must not be null"); - - return new TransformedValueMap<>(this, transformer); - } - - @Override - public ValueType put(final KeyType key, final ValueType val) { - if (key == null) throw new NullPointerException("Key must not be null"); - - return wrappedMap.put(key, val); - } - - @Override - public ValueType remove(final KeyType key) { - return wrappedMap.remove(key); - } - - @Override - public String toString() { - return wrappedMap.toString(); - } - - @Override - public IList<ValueType> valueList() { - final FunctionalList<ValueType> values = new FunctionalList<>(); - - 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(final Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (!(obj instanceof FunctionalMap)) return false; - - final 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 deleted file mode 100644 index e068b46..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java +++ /dev/null @@ -1,159 +0,0 @@ -package bjc.utils.funcdata; - -import java.util.StringTokenizer; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * A string tokenizer that exposes a functional interface - * - * @author ben - * - */ -public class FunctionalStringTokenizer { - /** - * Create a new tokenizer from the specified string. - * - * @param strang - * The string to create a tokenizer from. - * @return A new tokenizer that splits the provided string on spaces. - */ - public static FunctionalStringTokenizer fromString(final String strang) { - if (strang == null) throw new NullPointerException("String to tokenize must be non-null"); - - return new FunctionalStringTokenizer(new StringTokenizer(strang, " ")); - } - - /* - * The string tokenizer being driven - */ - private final StringTokenizer input; - - /** - * Create a functional string tokenizer from a given string - * - * @param inp - * The string to tokenize - */ - public FunctionalStringTokenizer(final String inp) { - if (inp == null) throw new NullPointerException("String to tokenize must be non-null"); - - this.input = new StringTokenizer(inp); - } - - /** - * Create a functional string tokenizer from a given string and set of - * separators - * - * @param input - * The string to tokenize - * @param seperators - * The set of separating tokens to use for splitting - */ - public FunctionalStringTokenizer(final String input, final String seperators) { - 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"); - - this.input = new StringTokenizer(input, seperators); - } - - /** - * Create a functional string tokenizer from a non-functional one - * - * @param toWrap - * The non-functional string tokenizer to wrap - */ - public FunctionalStringTokenizer(final StringTokenizer toWrap) { - if (toWrap == null) throw new NullPointerException("Wrapped tokenizer must not be null"); - - this.input = toWrap; - } - - /** - * Execute a provided action for each of the remaining tokens - * - * @param action - * The action to execute for each token - */ - public void forEachToken(final Consumer<String> action) { - if (action == null) throw new NullPointerException("Action must not be null"); - - while (input.hasMoreTokens()) { - action.accept(input.nextToken()); - } - } - - /** - * Get the string tokenizer encapsulated by this tokenizer - * - * @return The encapsulated tokenizer - */ - public StringTokenizer getInternal() { - return input; - } - - /** - * Check if this tokenizer has more tokens - * - * @return Whether or not this tokenizer has more tokens - */ - public boolean hasMoreTokens() { - return input.hasMoreTokens(); - } - - /** - * Return the next token from the tokenizer. - * - * Returns null if no more tokens are available - * - * @return The next token from the tokenizer - */ - public String nextToken() { - if (input.hasMoreTokens()) // Return the next available token - return input.nextToken(); - - // Return no token - return null; - } - - /** - * Convert this tokenizer into a list of strings - * - * @return This tokenizer, converted into a list of strings - */ - public IList<String> toList() { - return toList((final String element) -> element); - } - - /** - * Convert the contents of this tokenizer into a list. Consumes all of - * the input from this tokenizer. - * - * @param <E> - * The type of the converted tokens - * - * @param transformer - * The function to use to convert tokens. - * @return A list containing all of the converted tokens. - */ - public <E> IList<E> toList(final Function<String, E> transformer) { - if (transformer == null) throw new NullPointerException("Transformer must not be null"); - - final IList<E> returned = new FunctionalList<>(); - - // Add each token to the list after transforming it - forEachToken(token -> { - final E transformedToken = transformer.apply(token); - - returned.add(transformedToken); - }); - - 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 deleted file mode 100644 index 28c09d0..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IList.java +++ /dev/null @@ -1,416 +0,0 @@ -package bjc.utils.funcdata; - -import java.util.Comparator; -import java.util.Iterator; -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 java.util.stream.Collector; - -import bjc.utils.data.IPair; -import bjc.utils.functypes.ID; - -/** - * A wrapper over another list that provides functional operations over it. - * - * @author ben - * - * @param <ContainedType> - * The type in this list - */ -public interface IList<ContainedType> extends Iterable<ContainedType> { - /** - * Add an item to this list - * - * @param item - * The item to add to this list. - * @return Whether the item was added to the list successfully. - */ - boolean add(ContainedType item); - - /** - * Add all of the elements in the provided list to this list - * - * @param items - * The list of items to add - * @return True if every item was successfully added to the list, false - * otherwise - */ - default boolean addAll(final IList<ContainedType> items) { - return items.map(this::add).anyMatch(bl -> bl == false); - } - - /** - * Add all of the elements in the provided array to this list. - * - * @param items - * The array of items to add. - * - * @return True if every item was successfully added to the list, false - * otherwise. - */ - @SuppressWarnings("unchecked") - default boolean addAll(final ContainedType... items) { - boolean succ = true; - - for (final ContainedType item : items) { - final boolean addSucc = add(item); - - succ = succ ? addSucc : false; - } - - return succ; - } - - /** - * Check if all of the elements of this list match the specified - * predicate. - * - * @param matcher - * The predicate to use for checking. - * @return Whether all of the elements of the list match the specified - * predicate. - */ - boolean allMatch(Predicate<ContainedType> matcher); - - /** - * Check if any of the elements in this list match the specified list. - * - * @param matcher - * The predicate to use for checking. - * @return Whether any element in the list matches the provided - * predicate. - */ - boolean anyMatch(Predicate<ContainedType> matcher); - - /** - * Reduce the contents of this list using a collector - * - * @param <StateType> - * The intermediate accumulation type - * @param <ReducedType> - * The final, reduced type - * @param collector - * The collector to use for reduction - * @return The reduced list - */ - default <StateType, ReducedType> ReducedType collect( - final Collector<ContainedType, StateType, ReducedType> collector) { - final BiConsumer<StateType, ContainedType> accumulator = collector.accumulator(); - - final StateType initial = collector.supplier().get(); - return reduceAux(initial, (value, state) -> { - accumulator.accept(state, value); - - return state; - }, collector.finisher()); - } - - /** - * 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 <OtherType> - * The type of the second list - * @param <CombinedType> - * The type of the combined list - * - * @param list - * The list to combine with - * @param combiner - * The function to use for combining element pairs. - * @return A new list containing the merged pairs of lists. - */ - <OtherType, CombinedType> IList<CombinedType> combineWith(IList<OtherType> list, - BiFunction<ContainedType, OtherType, CombinedType> combiner); - - /** - * 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(ContainedType item); - - /** - * Get the first element in the list - * - * @return The first element in this list. - */ - ContainedType first(); - - /** - * Apply a function to each member of the list, then flatten the - * results. - * - * Does not change the underlying list. - * - * @param <MappedType> - * The type of the flattened list - * - * @param expander - * The function to apply to each member of the list. - * @return A new list containing the flattened results of applying the - * provided function. - */ - <MappedType> IList<MappedType> flatMap(Function<ContainedType, IList<MappedType>> expander); - - /** - * Apply a given action for each member of the list - * - * @param action - * The action to apply to each member of the list. - */ - @Override - void forEach(Consumer<? super ContainedType> action); - - /** - * Apply a given function to each element in the list and its index. - * - * @param action - * The function to apply to each element in the list and - * its index. - */ - void forEachIndexed(BiConsumer<Integer, ContainedType> action); - - /** - * 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. - */ - ContainedType getByIndex(int index); - - /** - * Retrieve a list containing all elements matching a predicate - * - * @param predicate - * The predicate to match by - * @return A list containing all elements that match the predicate - */ - IList<ContainedType> getMatching(Predicate<ContainedType> predicate); - - /** - * 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 <MappedType> - * The type of the transformed list - * - * @param transformer - * The function to apply to each element in the list - * @return A new list containing the mapped elements of this list. - */ - <MappedType> IList<MappedType> map(Function<ContainedType, MappedType> transformer); - - /** - * Zip two lists into a list of pairs - * - * @param <OtherType> - * The type of the second list - * - * @param list - * The list to use as the left side of the pair - * @return A list containing pairs of this element and the specified - * list - */ - <OtherType> IList<IPair<ContainedType, OtherType>> pairWith(IList<OtherType> list); - - /** - * Partition this list into a list of sublists - * - * @param partitionSize - * The size of elements to put into each one of the - * sublists - * @return A list partitioned into partitions of size nPerPart - */ - IList<IList<ContainedType>> partition(int partitionSize); - - /** - * Prepend an item to the list - * - * @param item - * The item to prepend to the list - */ - void prepend(ContainedType item); - - /** - * Prepend an array of items to the list. - * - * @param items - * The items to prepend to the list. - */ - @SuppressWarnings("unchecked") - default void prependAll(final ContainedType... items) { - for (final ContainedType item : items) { - prepend(item); - } - } - - /** - * Select a random item from the list, using a default random number - * generator - * - * @return A random item from the list - */ - default ContainedType randItem() { - return randItem(num -> (int) (Math.random() * num)); - } - - /** - * 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. - */ - ContainedType randItem(Function<Integer, Integer> rnd); - - /** - * Reduce this list to a single value, using a accumulative approach. - * - * @param <StateType> - * The in-between type of the values - * @param <ReducedType> - * The final value type - * - * @param initial - * The initial value of the accumulative state. - * @param accumulator - * The function to use to combine a list element with the - * accumulative state. - * @param transformer - * 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. - */ - <StateType, ReducedType> ReducedType reduceAux(StateType initial, - BiFunction<ContainedType, StateType, StateType> accumulator, - Function<StateType, ReducedType> transformer); - - /** - * Reduce this list to a single value, using a accumulative approach. - * - * @param <StateType> - * The in-between type of the values. - * - * @param initial - * The initial value of the accumulative state. - * - * @param accumulator - * The function to use to combine a list element with the - * accumulative state. - * - * @return A single value condensed from this list. - */ - default <StateType> StateType reduceAux(StateType initial, - BiFunction<ContainedType, StateType, StateType> accumulator) { - return reduceAux(initial, accumulator, ID.id()); - } - - /** - * Remove all elements that match a given predicate - * - * @param predicate - * The predicate to use to determine elements to delete - * @return Whether there was anything that satisfied the predicate - */ - boolean removeIf(Predicate<ContainedType> predicate); - - /** - * Remove all parameters that match a given parameter - * - * @param element - * The object to remove all matching copies of - */ - void removeMatching(ContainedType element); - - /** - * Reverse the contents of this list in place - */ - void reverse(); - - /** - * 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 key - * 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. - */ - ContainedType search(ContainedType key, Comparator<ContainedType> 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<ContainedType> comparator); - - /** - * Get the tail of this list (the list without the first element - * - * @return The list without the first element - */ - IList<ContainedType> tail(); - - /** - * Convert this list into an array - * - * @param type - * The type of array to return - * @return The list, as an array - */ - ContainedType[] toArray(ContainedType[] type); - - /** - * Convert the list into a Iterable - * - * @return An iterable view onto the list - */ - Iterable<ContainedType> toIterable(); - - @Override - default Iterator<ContainedType> iterator() { - return toIterable().iterator(); - } -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java deleted file mode 100644 index 0ee7375..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java +++ /dev/null @@ -1,188 +0,0 @@ -package bjc.utils.funcdata; - -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Functional wrapper over map providing some useful things. - * - * @author ben - * - * @param <KeyType> - * The type of this map's keys. - * - * @param <ValueType> - * The type of this map's values. - */ -public interface IMap<KeyType, ValueType> { - /** - * Execute an action for each entry in the map. - * - * @param action - * the action to execute for each entry in the map. - */ - void forEach(BiConsumer<KeyType, ValueType> action); - - /** - * Perform an action for each key in the map. - * - * @param action - * The action to perform on each key in the map. - */ - default void forEachKey(final Consumer<KeyType> action) { - forEach((key, val) -> action.accept(key)); - } - - /** - * Perform an action for each value in the map. - * - * @param action - * The action to perform on each value in the map. - */ - default void forEachValue(final Consumer<ValueType> action) { - forEach((key, val) -> action.accept(val)); - } - - /** - * 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(KeyType key); - - /** - * Get the value assigned to the given key. - * - * @param key - * The key to look for a value under. - * - * @return The value of the key. - */ - ValueType get(KeyType key); - - /** - * Get a value from the map, and return a default value if the key - * doesn't exist. - * - * @param key - * The key to attempt to retrieve. - * - * @param defaultValue - * The value to return if the key doesn't exist. - * - * @return The value associated with the key, or the default value if - * the key doesn't exist. - */ - default ValueType getOrDefault(final KeyType key, final ValueType defaultValue) { - try { - return get(key); - } catch (final IllegalArgumentException iaex) { - /* - * We don't care about this, because it indicates a key - * is missing. - */ - return defaultValue; - } - } - - /** - * 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 - */ - ValueType put(KeyType key, ValueType val); - - /** - * Delete all the values in the map. - */ - default void clear() { - keyList().forEach(key -> remove(key)); - } - - /** - * Get the number of entries in this map. - * - * @return The number of entries in this map. - */ - default int size() { - return keyList().getSize(); - } - - /** - * 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. - */ - default <V2> IMap<KeyType, V2> transform(final Function<ValueType, V2> transformer) { - return new TransformedValueMap<>(this, transformer); - } - - /** - * Extends this map, creating a new map that will delegate queries to - * the map, but store any added values itself. - * - * @return An extended map. - */ - IMap<KeyType, ValueType> extend(); - - /** - * 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 received null, - * doesn't mean the map wasn't changed. It may mean that someone - * put a null value for that key into the map. - */ - ValueType remove(KeyType key); - - /** - * Get a list of all the keys in this map. - * - * @return A list of all the keys in this map. - */ - IList<KeyType> keyList(); - - /** - * Get a list of the values in this map. - * - * @return A list of values in this map. - */ - default IList<ValueType> valueList() { - final IList<ValueType> returns = new FunctionalList<>(); - - for (final KeyType key : keyList()) { - returns.add(get(key)); - } - - return returns; - } -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/SentryList.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/SentryList.java deleted file mode 100644 index c322743..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/SentryList.java +++ /dev/null @@ -1,41 +0,0 @@ -package bjc.utils.funcdata; - -import java.util.List; - -/** - * A list that logs when items are inserted into it. - * - * @author bjculkin - * - * @param <T> - * The type of item in the list. - */ -public class SentryList<T> extends FunctionalList<T> { - /** - * Create a new sentry list. - */ - public SentryList() { - super(); - } - - /** - * Create a new sentry list backed by an existing list. - * - * @param backing - * The backing list. - */ - public SentryList(final List<T> backing) { - super(backing); - } - - @Override - public boolean add(final T item) { - final boolean val = super.add(item); - - if (val) { - System.out.println("Added item (" + item + ") to list"); - } - - return val; - } -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java deleted file mode 100644 index 0ca1fdc..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java +++ /dev/null @@ -1,102 +0,0 @@ -package bjc.utils.funcdata; - -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * A map that transforms values from one type to another - * - * @author ben - * - * @param <OldKey> - * The type of the map's keys - * @param <OldValue> - * The type of the map's values - * @param <NewValue> - * The type of the transformed values - */ -final class TransformedValueMap<OldKey, OldValue, NewValue> implements IMap<OldKey, NewValue> { - private final IMap<OldKey, OldValue> backing; - private final Function<OldValue, NewValue> transformer; - - public TransformedValueMap(final IMap<OldKey, OldValue> backingMap, - final Function<OldValue, NewValue> transform) { - backing = backingMap; - transformer = transform; - } - - @Override - public void clear() { - backing.clear(); - } - - @Override - public boolean containsKey(final OldKey key) { - return backing.containsKey(key); - } - - @Override - public IMap<OldKey, NewValue> extend() { - return new ExtendedMap<>(this, new FunctionalMap<>()); - } - - @Override - public void forEach(final BiConsumer<OldKey, NewValue> action) { - backing.forEach((key, value) -> { - action.accept(key, transformer.apply(value)); - }); - } - - @Override - public void forEachKey(final Consumer<OldKey> action) { - backing.forEachKey(action); - } - - @Override - public void forEachValue(final Consumer<NewValue> action) { - backing.forEachValue(value -> { - action.accept(transformer.apply(value)); - }); - } - - @Override - public NewValue get(final OldKey key) { - return transformer.apply(backing.get(key)); - } - - @Override - public int size() { - return backing.size(); - } - - @Override - public IList<OldKey> keyList() { - return backing.keyList(); - } - - @Override - public <MappedValue> IMap<OldKey, MappedValue> transform(final Function<NewValue, MappedValue> transform) { - return new TransformedValueMap<>(this, transform); - } - - @Override - public NewValue put(final OldKey key, final NewValue value) { - throw new UnsupportedOperationException("Can't add items to transformed map"); - } - - @Override - public NewValue remove(final OldKey key) { - return transformer.apply(backing.remove(key)); - } - - @Override - public String toString() { - return backing.toString(); - } - - @Override - public IList<NewValue> valueList() { - return backing.valueList().map(transformer); - } -} 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 deleted file mode 100644 index 8acd477..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java +++ /dev/null @@ -1,221 +0,0 @@ -package bjc.utils.funcdata.bst; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.function.Predicate; - -import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IList; - -/** - * A binary search tree, with some mild support for functional traversal. - * - * @author ben - * - * @param <T> - * The data type stored in the node. - */ -public class BinarySearchTree<T> { - /* - * The comparator for use in ordering items - */ - private final Comparator<T> comparator; - - /* - * The current count of elements in the tree - */ - private int elementCount; - - /* - * The root element of the tree - */ - private ITreePart<T> root; - - /** - * Create a new tree using the specified way to compare elements. - * - * @param cmp - * The thing to use for comparing elements - */ - public BinarySearchTree(final Comparator<T> cmp) { - if (cmp == null) throw new NullPointerException("Comparator must not be null"); - - elementCount = 0; - comparator = cmp; - } - - /** - * Add a node to the binary search tree. - * - * @param element - * The data to add to the binary search tree. - */ - public void addNode(final T element) { - elementCount++; - - if (root == null) { - root = new BinarySearchTreeNode<>(element, null, null); - } else { - root.add(element, comparator); - } - } - - /** - * Check if an adjusted pivot falls with the bounds of a list - * - * @param elements - * The list to get bounds from - * @param pivot - * The pivot - * @param pivotAdjustment - * The distance from the pivot - * @return Whether the adjusted pivot is with the list - */ - private boolean adjustedPivotInBounds(final IList<T> elements, final int pivot, final int pivotAdjustment) { - return pivot - pivotAdjustment >= 0 && pivot + pivotAdjustment < elements.getSize(); - } - - /** - * Balance the tree, and remove soft-deleted nodes for free. - * - * Takes O(N) time, but also O(N) space. - */ - public void balance() { - final IList<T> elements = new FunctionalList<>(); - - // Add each element to the list in sorted order - root.forEach(TreeLinearizationMethod.INORDER, element -> elements.add(element)); - - // Clear the tree - root = null; - - // Set up the pivot and adjustment for readding elements - final int pivot = elements.getSize() / 2; - int pivotAdjustment = 0; - - // Add elements until there aren't any left - while (adjustedPivotInBounds(elements, pivot, pivotAdjustment)) { - if (root == null) { - // Create a new root element - root = new BinarySearchTreeNode<>(elements.getByIndex(pivot), null, null); - } else { - // Add the left and right elements in a balanced - // manner - root.add(elements.getByIndex(pivot + pivotAdjustment), comparator); - - root.add(elements.getByIndex(pivot - pivotAdjustment), comparator); - } - - // Increase the distance from the pivot - pivotAdjustment++; - } - - // Add any trailing unbalanced elements - if (pivot - pivotAdjustment >= 0) { - root.add(elements.getByIndex(pivot - pivotAdjustment), comparator); - } else if (pivot + pivotAdjustment < elements.getSize()) { - root.add(elements.getByIndex(pivot + pivotAdjustment), comparator); - } - } - - /** - * Soft-delete a node from the tree. - * - * Soft-deleted nodes stay in the tree until trim()/balance() is - * invoked, and are not included in traversals/finds. - * - * @param element - * The node to delete - */ - public void deleteNode(final T element) { - elementCount--; - - root.delete(element, comparator); - } - - /** - * Get the root of the tree. - * - * @return The root of the tree. - */ - public ITreePart<T> getRoot() { - return root; - } - - /** - * Check if a node is in the tree - * - * @param element - * The node to check the presence of for the tree. - * @return Whether or not the node is in the tree. - */ - public boolean isInTree(final T element) { - return root.contains(element, comparator); - } - - /** - * Traverse the tree in a specified way until the function fails - * - * @param linearizationMethod - * The way to linearize the tree for traversal - * @param traversalPredicate - * The function to use until it fails - */ - public void traverse(final TreeLinearizationMethod linearizationMethod, final 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"); - - root.forEach(linearizationMethod, traversalPredicate); - } - - /** - * Remove all soft-deleted nodes from the tree. - */ - public void trim() { - final List<T> nodes = new ArrayList<>(elementCount); - - // Add all non-soft deleted nodes to the tree in insertion order - traverse(TreeLinearizationMethod.PREORDER, node -> { - nodes.add(node); - return true; - }); - - // Clear the tree - root = null; - - // 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(final Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (!(obj instanceof BinarySearchTree<?>)) return false; - - final 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 deleted file mode 100644 index 8c4f3f0..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeLeaf.java +++ /dev/null @@ -1,119 +0,0 @@ -package bjc.utils.funcdata.bst; - -import java.util.Comparator; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.function.Predicate; - -/** - * A leaf in a tree. - * - * @author ben - * - * @param <T> - * The data stored in the tree. - */ -public class BinarySearchTreeLeaf<T> implements ITreePart<T> { - /** - * The data held in this tree leaf - */ - protected T data; - - /** - * Whether this node is soft-deleted or not - */ - protected boolean isDeleted; - - /** - * Create a new leaf holding the specified data. - * - * @param element - * The data for the leaf to hold. - */ - public BinarySearchTreeLeaf(final T element) { - data = element; - } - - @Override - public void add(final T element, final Comparator<T> comparator) { - throw new IllegalArgumentException("Can't add to a leaf."); - } - - @Override - public <E> E collapse(final Function<T, E> leafTransformer, final BiFunction<E, E, E> branchCollapser) { - if (leafTransformer == null) throw new NullPointerException("Transformer must not be null"); - - return leafTransformer.apply(data); - } - - @Override - public boolean contains(final T element, final Comparator<T> comparator) { - return this.data.equals(element); - } - - @Override - public T data() { - return data; - } - - @Override - public void delete(final T element, final Comparator<T> comparator) { - if (data.equals(element)) { - isDeleted = true; - } - } - - @Override - public boolean directedWalk(final DirectedWalkFunction<T> treeWalker) { - if (treeWalker == null) throw new NullPointerException("Tree walker must not be null"); - - switch (treeWalker.walk(data)) { - case SUCCESS: - return true; - // We don't have any children to care about - case FAILURE: - case LEFT: - case RIGHT: - default: - return false; - } - } - - @Override - public boolean forEach(final TreeLinearizationMethod linearizationMethod, - final Predicate<T> traversalPredicate) { - 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(final Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (!(obj instanceof BinarySearchTreeLeaf<?>)) return false; - - final 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 deleted file mode 100644 index 9f45c17..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java +++ /dev/null @@ -1,287 +0,0 @@ -package bjc.utils.funcdata.bst; - -import static bjc.utils.funcdata.bst.DirectedWalkFunction.DirectedWalkResult.FAILURE; -import static bjc.utils.funcdata.bst.DirectedWalkFunction.DirectedWalkResult.LEFT; -import static bjc.utils.funcdata.bst.DirectedWalkFunction.DirectedWalkResult.RIGHT; -import static bjc.utils.funcdata.bst.DirectedWalkFunction.DirectedWalkResult.SUCCESS; - -import java.util.Comparator; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.function.Predicate; - -/** - * A binary node in a tree. - * - * @author ben - * - * @param <T> - * The data type stored in the tree. - */ -public class BinarySearchTreeNode<T> extends BinarySearchTreeLeaf<T> { - /* - * The left child of this node - */ - private ITreePart<T> left; - - /* - * The right child of this node - */ - private ITreePart<T> right; - - /** - * Create a new node with the specified data and children. - * - * @param element - * The data to store in this node. - * @param lft - * The left child of this node. - * @param rght - * The right child of this node. - */ - public BinarySearchTreeNode(final T element, final ITreePart<T> lft, final ITreePart<T> rght) { - super(element); - this.left = lft; - this.right = rght; - } - - @Override - public void add(final T element, final Comparator<T> comparator) { - if (comparator == null) throw new NullPointerException("Comparator must not be null"); - - switch (comparator.compare(data, element)) { - case -1: - if (left == null) { - left = new BinarySearchTreeNode<>(element, null, null); - } else { - left.add(element, comparator); - } - break; - case 0: - if (isDeleted) { - isDeleted = false; - } else throw new IllegalArgumentException("Can't add duplicate values"); - break; - case 1: - if (right == null) { - right = new BinarySearchTreeNode<>(element, null, null); - } else { - right.add(element, comparator); - } - break; - default: - throw new IllegalStateException("Error: Comparator yielded invalid value"); - } - } - - @Override - public <E> E collapse(final Function<T, E> nodeCollapser, final BiFunction<E, E, E> branchCollapser) { - if (nodeCollapser == null || branchCollapser == null) - throw new NullPointerException("Collapser must not be null"); - - final E collapsedNode = nodeCollapser.apply(data); - - if (left != null) { - final E collapsedLeftBranch = left.collapse(nodeCollapser, branchCollapser); - - if (right != null) { - final E collapsedRightBranch = right.collapse(nodeCollapser, branchCollapser); - - final E collapsedBranches = branchCollapser.apply(collapsedLeftBranch, - collapsedRightBranch); - - return branchCollapser.apply(collapsedNode, collapsedBranches); - } - - return branchCollapser.apply(collapsedNode, collapsedLeftBranch); - } - - if (right != null) { - final E collapsedRightBranch = right.collapse(nodeCollapser, branchCollapser); - - return branchCollapser.apply(collapsedNode, collapsedRightBranch); - } - - return collapsedNode; - } - - @Override - public boolean contains(final T element, final Comparator<T> comparator) { - if (comparator == null) throw new NullPointerException("Comparator must not be null"); - - return directedWalk(currentElement -> { - switch (comparator.compare(element, currentElement)) { - case -1: - return LEFT; - case 0: - return isDeleted ? FAILURE : SUCCESS; - case 1: - return RIGHT; - default: - return FAILURE; - } - }); - } - - @Override - public void delete(final T element, final Comparator<T> comparator) { - if (comparator == null) throw new NullPointerException("Comparator must not be null"); - - directedWalk(currentElement -> { - switch (comparator.compare(data, element)) { - case -1: - return left == null ? FAILURE : LEFT; - case 0: - isDeleted = true; - return FAILURE; - case 1: - return right == null ? FAILURE : RIGHT; - default: - return FAILURE; - } - }); - } - - @Override - public boolean directedWalk(final DirectedWalkFunction<T> treeWalker) { - if (treeWalker == null) throw new NullPointerException("Walker must not be null"); - - switch (treeWalker.walk(data)) { - case SUCCESS: - return true; - case LEFT: - return left.directedWalk(treeWalker); - case RIGHT: - return right.directedWalk(treeWalker); - case FAILURE: - return false; - default: - return false; - } - } - - @Override - public boolean forEach(final TreeLinearizationMethod linearizationMethod, - final 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, traversalPredicate); - case INORDER: - return inorderTraverse(linearizationMethod, traversalPredicate); - case POSTORDER: - return postorderTraverse(linearizationMethod, traversalPredicate); - default: - throw new IllegalArgumentException( - "Passed an incorrect TreeLinearizationMethod " + linearizationMethod + ". WAT"); - } - } - - private boolean inorderTraverse(final TreeLinearizationMethod linearizationMethod, - final Predicate<T> traversalPredicate) { - if (!traverseLeftBranch(linearizationMethod, traversalPredicate)) return false; - - if (!traverseElement(traversalPredicate)) return false; - - if (!traverseRightBranch(linearizationMethod, traversalPredicate)) return false; - - return true; - } - - private boolean postorderTraverse(final TreeLinearizationMethod linearizationMethod, - final Predicate<T> traversalPredicate) { - if (!traverseLeftBranch(linearizationMethod, traversalPredicate)) return false; - - if (!traverseRightBranch(linearizationMethod, traversalPredicate)) return false; - - if (!traverseElement(traversalPredicate)) return false; - - return true; - - } - - private boolean preorderTraverse(final TreeLinearizationMethod linearizationMethod, - final Predicate<T> traversalPredicate) { - if (!traverseElement(traversalPredicate)) return false; - - if (!traverseLeftBranch(linearizationMethod, traversalPredicate)) return false; - - if (!traverseRightBranch(linearizationMethod, traversalPredicate)) return false; - - return true; - } - - private boolean traverseElement(final Predicate<T> traversalPredicate) { - boolean nodeSuccesfullyTraversed; - - if (isDeleted) { - nodeSuccesfullyTraversed = true; - } else { - nodeSuccesfullyTraversed = traversalPredicate.test(data); - } - - return nodeSuccesfullyTraversed; - } - - private boolean traverseLeftBranch(final TreeLinearizationMethod linearizationMethod, - final Predicate<T> traversalPredicate) { - boolean leftSuccesfullyTraversed; - - if (left == null) { - leftSuccesfullyTraversed = true; - } else { - leftSuccesfullyTraversed = left.forEach(linearizationMethod, traversalPredicate); - } - - return leftSuccesfullyTraversed; - } - - private boolean traverseRightBranch(final TreeLinearizationMethod linearizationMethod, - final Predicate<T> traversalPredicate) { - boolean rightSuccesfullyTraversed; - - if (right == null) { - rightSuccesfullyTraversed = true; - } else { - rightSuccesfullyTraversed = right.forEach(linearizationMethod, traversalPredicate); - } - - 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(final Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - if (!(obj instanceof BinarySearchTreeNode<?>)) return false; - - final 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; - } -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/DirectedWalkFunction.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/DirectedWalkFunction.java deleted file mode 100644 index e11524a..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/DirectedWalkFunction.java +++ /dev/null @@ -1,49 +0,0 @@ -package bjc.utils.funcdata.bst; - -/** - * Represents a function for doing a directed walk of a binary tree. - * - * @author ben - * - * @param <T> - * The type of element stored in the walked tree - */ -@FunctionalInterface -public interface DirectedWalkFunction<T> { - /** - * Represents the results used to direct a walk in a binary tree. - * - * @author ben - * - */ - public enum DirectedWalkResult { - /** - * Specifies that the function has failed. - */ - FAILURE, - /** - * Specifies that the function wants to move left in the tree - * next. - */ - LEFT, - /** - * Specifies that the function wants to move right in the tree - * next. - */ - RIGHT, - /** - * Specifies that the function has succesfully completed - * - */ - SUCCESS - } - - /** - * Perform a directed walk on a node of a tree. - * - * @param element - * The data stored in the node currently being visited - * @return The way the function wants the walk to go next. - */ - public DirectedWalkResult walk(T element); -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/ITreePart.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/ITreePart.java deleted file mode 100644 index 3aa8880..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/ITreePart.java +++ /dev/null @@ -1,96 +0,0 @@ -package bjc.utils.funcdata.bst; - -import java.util.Comparator; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.function.Predicate; - -/** - * A interface for the fundamental things that want to be part of a tree. - * - * @author ben - * - * @param <T> - * The data contained in this part of the tree. - */ -public interface ITreePart<T> { - /** - * Add a element below this tree part somewhere. - * - * @param element - * The element to add below this tree part - * @param comparator - * The thing to use for comparing values to find where to - * insert the tree part. - */ - public void add(T element, Comparator<T> comparator); - - /** - * Collapses this tree part into a single value. Does not change the - * underlying tree. - * - * @param <E> - * The type of the final collapsed value - * - * @param nodeCollapser - * The function to use to transform data into mapped - * form. - * @param branchCollapser - * The function to use to collapse data in mapped form - * into a single value. - * @return A single value from collapsing the tree. - */ - public <E> E collapse(Function<T, E> nodeCollapser, BiFunction<E, E, E> branchCollapser); - - /** - * Check if this tre part or below it contains the specified data item - * - * @param element - * The data item to look for. - * @param comparator - * The comparator to use to search for the data item - * @return Whether or not the given item is contained in this tree part - * or its children. - */ - public boolean contains(T element, Comparator<T> comparator); - - /** - * Get the data associated with this tree part. - * - * @return The data associated with this tree part. - */ - public T data(); - - /** - * Remove the given node from this tree part and any of its children. - * - * @param element - * The data item to remove. - * @param comparator - * The comparator to use to search for the data item. - */ - public void delete(T element, Comparator<T> comparator); - - /** - * Execute a directed walk through the tree. - * - * @param walker - * The function to use to direct the walk through the - * tree. - * @return Whether the directed walk finished successfully. - */ - public boolean directedWalk(DirectedWalkFunction<T> walker); - - /** - * Execute a provided function for each element of tree it succesfully - * completes for - * - * @param linearizationMethod - * The way to linearize the tree for executing - * @param predicate - * The predicate to apply to each element, where it - * returning false terminates traversal early - * @return Whether the traversal finished succesfully - */ - public boolean forEach(TreeLinearizationMethod linearizationMethod, Predicate<T> predicate); -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/TreeLinearizationMethod.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/TreeLinearizationMethod.java deleted file mode 100644 index 0c83867..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/TreeLinearizationMethod.java +++ /dev/null @@ -1,25 +0,0 @@ -package bjc.utils.funcdata.bst; - -/** - * Represents the ways to linearize a tree for traversal. - * - * @author ben - * - */ -public enum TreeLinearizationMethod { - /** - * Visit the left side of this tree part, the tree part itself, and then - * the right part. - */ - INORDER, - /** - * Visit the left side of this tree part, the right side, and then the - * tree part itself. - */ - POSTORDER, - /** - * Visit the tree part itself, then the left side of tthis tree part and - * then the right part. - */ - PREORDER -}
\ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Bifunctor.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Bifunctor.java deleted file mode 100644 index 13c1709..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Bifunctor.java +++ /dev/null @@ -1,139 +0,0 @@ -package bjc.utils.funcdata.theory; - -import java.util.function.Function; - -/** - * A functor over a pair of heterogeneous types - * - * @author ben - * @param <LeftType> - * The type stored on the 'left' of the pair - * @param <RightType> - * The type stored on the 'right' of the pair - * - */ -public interface Bifunctor<LeftType, RightType> { - /** - * Alias for functor mapping. - * - * @author EVE - * - * @param <OldLeft> - * @param <OldRight> - * @param <NewLeft> - * @param <NewRight> - */ - public interface BifunctorMap<OldLeft, OldRight, NewLeft, NewRight> - extends Function<Bifunctor<OldLeft, OldRight>, Bifunctor<NewLeft, NewRight>> { - - } - - /** - * Alias for left functor mapping. - * - * @author EVE - * - * @param <OldLeft> - * @param <OldRight> - * @param <NewLeft> - */ - public interface LeftBifunctorMap<OldLeft, OldRight, NewLeft> - extends BifunctorMap<OldLeft, OldRight, NewLeft, OldRight> { - - } - - /** - * Alias for right functor mapping. - * - * @author EVE - * - * @param <OldLeft> - * @param <OldRight> - * @param <NewRight> - */ - public interface RightBifunctorMap<OldLeft, OldRight, NewRight> - extends BifunctorMap<OldLeft, OldRight, OldLeft, NewRight> { - - } - - /** - * Lift a pair of functions to a single function that maps over both - * parts of a pair - * - * @param <OldLeft> - * The old left type of the pair - * @param <OldRight> - * The old right type of the pair - * @param <NewLeft> - * The new left type of the pair - * @param <NewRight> - * The new right type of the pair - * @param leftFunc - * The function that maps over the left of the pair - * @param rightFunc - * The function that maps over the right of the pair - * @return A function that maps over both parts of the pair - */ - public default <OldLeft, OldRight, NewLeft, NewRight> BifunctorMap<OldLeft, OldRight, NewLeft, NewRight> bimap( - final Function<OldLeft, NewLeft> leftFunc, final Function<OldRight, NewRight> rightFunc) { - final BifunctorMap<OldLeft, OldRight, NewLeft, NewRight> bimappedFunc = (argPair) -> { - final LeftBifunctorMap<OldLeft, OldRight, NewLeft> leftMapper = argPair.fmapLeft(leftFunc); - - final Bifunctor<NewLeft, OldRight> leftMappedFunctor = leftMapper.apply(argPair); - final RightBifunctorMap<NewLeft, OldRight, NewRight> rightMapper = leftMappedFunctor - .fmapRight(rightFunc); - - return rightMapper.apply(leftMappedFunctor); - }; - - return bimappedFunc; - } - - /** - * Lift a function to operate over the left part of this pair - * - * @param <OldLeft> - * The old left type of the pair - * @param <OldRight> - * The old right type of the pair - * @param <NewLeft> - * The new left type of the pair - * @param func - * The function to lift to work over the left side of the - * pair - * @return The function lifted to work over the left side of bifunctors - */ - public <OldLeft, OldRight, NewLeft> LeftBifunctorMap<OldLeft, OldRight, NewLeft> fmapLeft( - Function<OldLeft, NewLeft> func); - - /** - * Lift a function to operate over the right part of this pair - * - * @param <OldLeft> - * The old left type of the pair - * @param <OldRight> - * The old right type of the pair - * @param <NewRight> - * The new right type of the pair - * @param func - * The function to lift to work over the right side of - * the pair - * @return The function lifted to work over the right side of bifunctors - */ - public <OldLeft, OldRight, NewRight> RightBifunctorMap<OldLeft, OldRight, NewRight> fmapRight( - Function<OldRight, NewRight> func); - - /** - * Get the value contained on the left of this bifunctor - * - * @return The value on the left side of this bifunctor - */ - public LeftType getLeft(); - - /** - * Get the value contained on the right of this bifunctor - * - * @return The value on the right of this bifunctor - */ - public RightType getRight(); -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Functor.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Functor.java deleted file mode 100644 index 1c53284..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Functor.java +++ /dev/null @@ -1,39 +0,0 @@ -package bjc.utils.funcdata.theory; - -import java.util.function.Function; - -/** - * Represents a container or context some sort usually, but the precise - * definition is that it represents exactly what it is defined as - * - * @author ben - * @param <ContainedType> - * The value inside the functor - */ -public interface Functor<ContainedType> { - /** - * Converts a normal function to operate over values in a functor. - * - * N.B: Even though the type signature implies that you can apply the - * resulting function to any type of functor, it is only safe to call it - * on instances of the type of functor you called fmap on. - * - * @param <ArgType> - * The argument of the function - * @param <ReturnType> - * The return type of the function - * @param func - * The function to convert - * @return The passed in function converted to work over a particular - * type of functors - */ - public <ArgType, ReturnType> Function<Functor<ArgType>, Functor<ReturnType>> fmap( - Function<ArgType, ReturnType> func); - - /** - * Retrieve the thing inside this functor - * - * @return The thing inside this functor - */ - public ContainedType getValue(); -} |
