From 0a8f34c27c6ef93c5c94d17728af62c7607e225f Mon Sep 17 00:00:00 2001 From: Ben Culkin Date: Thu, 3 Dec 2020 19:21:38 -0500 Subject: Rename types to match Java style This renames several interfaces that had names like IWhatever, since that isn't a style that Java uses --- src/main/java/bjc/funcdata/ExtendedMap.java | 14 +- src/main/java/bjc/funcdata/Freezable.java | 73 ++++ src/main/java/bjc/funcdata/FunctionalList.java | 50 +-- src/main/java/bjc/funcdata/FunctionalMap.java | 10 +- .../bjc/funcdata/FunctionalStringTokenizer.java | 6 +- src/main/java/bjc/funcdata/IFreezable.java | 73 ---- src/main/java/bjc/funcdata/IList.java | 455 --------------------- src/main/java/bjc/funcdata/IMap.java | 216 ---------- src/main/java/bjc/funcdata/ListEx.java | 455 +++++++++++++++++++++ src/main/java/bjc/funcdata/MapEx.java | 216 ++++++++++ src/main/java/bjc/funcdata/ObjectFrozen.java | 2 +- .../java/bjc/funcdata/TransformedValueMap.java | 8 +- .../java/bjc/funcdata/bst/BinarySearchTree.java | 10 +- .../bjc/funcdata/bst/BinarySearchTreeLeaf.java | 2 +- .../bjc/funcdata/bst/BinarySearchTreeNode.java | 8 +- src/main/java/bjc/funcdata/bst/ITreePart.java | 107 ----- src/main/java/bjc/funcdata/bst/TreePart.java | 107 +++++ 17 files changed, 906 insertions(+), 906 deletions(-) create mode 100644 src/main/java/bjc/funcdata/Freezable.java delete mode 100644 src/main/java/bjc/funcdata/IFreezable.java delete mode 100644 src/main/java/bjc/funcdata/IList.java delete mode 100644 src/main/java/bjc/funcdata/IMap.java create mode 100644 src/main/java/bjc/funcdata/ListEx.java create mode 100644 src/main/java/bjc/funcdata/MapEx.java delete mode 100644 src/main/java/bjc/funcdata/bst/ITreePart.java create mode 100644 src/main/java/bjc/funcdata/bst/TreePart.java (limited to 'src/main/java/bjc/funcdata') diff --git a/src/main/java/bjc/funcdata/ExtendedMap.java b/src/main/java/bjc/funcdata/ExtendedMap.java index 9638cdc..379ff65 100644 --- a/src/main/java/bjc/funcdata/ExtendedMap.java +++ b/src/main/java/bjc/funcdata/ExtendedMap.java @@ -15,11 +15,11 @@ import java.util.function.*; * @param * The type of the values of the map. */ -class ExtendedMap implements IMap { +class ExtendedMap implements MapEx { /* The map we delegate lookups to. */ - private final IMap delegate; + private final MapEx delegate; /* The map we store things in. */ - private final IMap store; + private final MapEx store; private boolean isFrozen = false; private boolean thawEnabled = true; @@ -33,8 +33,8 @@ class ExtendedMap implements IMap { * @param store * The map to store things in. */ - public ExtendedMap(final IMap delegate, - final IMap store) { + public ExtendedMap(final MapEx delegate, + final MapEx store) { this.delegate = delegate; this.store = store; } @@ -71,8 +71,8 @@ class ExtendedMap implements IMap { } @Override - public IList keyList() { - IList ilst = new FunctionalList<>(); + public ListEx keyList() { + ListEx ilst = new FunctionalList<>(); ilst.addAll(store.keyList()); ilst.addAll(delegate.keyList()); diff --git a/src/main/java/bjc/funcdata/Freezable.java b/src/main/java/bjc/funcdata/Freezable.java new file mode 100644 index 0000000..e83accb --- /dev/null +++ b/src/main/java/bjc/funcdata/Freezable.java @@ -0,0 +1,73 @@ +package bjc.funcdata; + +/** + * Indicates that an object can switch between immutable and mutable modes. + * + * Note that this only implements 'shallow' immutability. Namely, any sub-objects + * are not made immutable, and if the type is a collection, the elements are still + * as mutable as they were before. + * + * Implementations of this interface may choose to throw {@link ObjectFrozen} if + * you attempt to modify a frozen object, but they may also choose not to. + * + * @author Ben Culkin + */ +public interface Freezable { + /** + * Freezes the internal state of this object, making it immutable. + * + * @return True if the object is frozen, false if it couldn't be frozen. + */ + public boolean freeze(); + /** + * Thaws the internal state of this object, making it mutable. + * + * @return True if the object is thawed, false if it couldn't be thawed. + */ + public boolean thaw(); + + /** + * 'Deep-freeze' this object, making it immutable and disabling the ability to + * thaw it. + * + * @return True if the object was deep-frozen, false if that couldn't happen. + */ + default boolean deepFreeze() { + return false; + } + + /** + * Check if this object can be frozen. + * + * @return Whether or not the object can be frozen. + */ + default boolean canFreeze() { + return false; + } + + /** + * Checks if this object can be thawed. + * + * @return Whether or not the object can be thawed. + */ + default boolean canThaw() { + return false; + } + + /** + * Determines if this object is frozen. + * + * @return True if the object is frozen, false if the object is thawed. + */ + public boolean isFrozen(); + + + /** + * Determines if this object is thawed. + * + * @return True if the object is thawed, false if the object is thawed. + */ + default boolean isThawed() { + return !isFrozen(); + } +} diff --git a/src/main/java/bjc/funcdata/FunctionalList.java b/src/main/java/bjc/funcdata/FunctionalList.java index 2cdfa27..f9c06a3 100644 --- a/src/main/java/bjc/funcdata/FunctionalList.java +++ b/src/main/java/bjc/funcdata/FunctionalList.java @@ -12,10 +12,10 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; -import bjc.data.IHolder; -import bjc.data.IPair; -import bjc.data.Identity; +import bjc.data.Holder; import bjc.data.Pair; +import bjc.data.Identity; +import bjc.data.SimplePair; /** * A wrapper over another list that provides eager functional operations over @@ -29,7 +29,7 @@ import bjc.data.Pair; * @param * The type in this list */ -public class FunctionalList implements Cloneable, IList { +public class FunctionalList implements Cloneable, ListEx { /* The list used as a backing store */ private final List wrapped; @@ -65,7 +65,7 @@ public class FunctionalList implements Cloneable, IList { * @return The returned list. */ @SafeVarargs - public static IList listOf(final T... items) { + public static ListEx listOf(final T... items) { return new FunctionalList<>(items); } @@ -137,8 +137,8 @@ public class FunctionalList implements Cloneable, IList { * @return A copy of the list. */ @Override - public IList clone() { - final IList cloned = new FunctionalList<>(); + public ListEx clone() { + final ListEx cloned = new FunctionalList<>(); for (final E element : wrapped) { cloned.add(element); @@ -148,7 +148,7 @@ public class FunctionalList implements Cloneable, IList { } @Override - public IList combineWith(final IList rightList, + public ListEx combineWith(final ListEx rightList, final BiFunction itemCombiner) { if (rightList == null) { throw new NullPointerException("Target combine list must not be null"); @@ -156,7 +156,7 @@ public class FunctionalList implements Cloneable, IList { throw new NullPointerException("Combiner must not be null"); } - final IList returned = new FunctionalList<>(); + final ListEx returned = new FunctionalList<>(); /* Get the iterator for the other list. */ final Iterator rightIterator = rightList.toIterable().iterator(); @@ -222,14 +222,14 @@ public class FunctionalList implements Cloneable, IList { } @Override - public IList flatMap(final Function> expander) { + public ListEx flatMap(final Function> expander) { if (expander == null) throw new NullPointerException("Expander must not be null"); - final IList returned = new FunctionalList<>(this.wrapped.size()); + final ListEx returned = new FunctionalList<>(this.wrapped.size()); forEach(element -> { - final IList expandedElement = expander.apply(element); + final ListEx expandedElement = expander.apply(element); if (expandedElement == null) throw new NullPointerException("Expander returned null list"); @@ -257,7 +257,7 @@ public class FunctionalList implements Cloneable, IList { /* * This is held b/c ref'd variables must be final/effectively final. */ - final IHolder currentIndex = new Identity<>(0); + final Holder currentIndex = new Identity<>(0); wrapped.forEach(element -> { /* Call the action with the index and the value. */ @@ -283,11 +283,11 @@ public class FunctionalList implements Cloneable, IList { } @Override - public IList getMatching(final Predicate predicate) { + public ListEx getMatching(final Predicate predicate) { if (predicate == null) throw new NullPointerException("Predicate must not be null"); - final IList returned = new FunctionalList<>(); + final ListEx returned = new FunctionalList<>(); wrapped.forEach(element -> { if (predicate.test(element)) { @@ -313,17 +313,17 @@ public class FunctionalList implements Cloneable, IList { /* Check if a partition has room for another item. */ private Boolean isPartitionFull(final int numberPerPartition, - final IHolder> currentPartition) { + final Holder> currentPartition) { return currentPartition .unwrap(partition -> partition.getSize() >= numberPerPartition); } @Override - public IList map(final Function elementTransformer) { + public ListEx map(final Function elementTransformer) { if (elementTransformer == null) throw new NullPointerException("Transformer must be not null"); - final IList returned = new FunctionalList<>(this.wrapped.size()); + final ListEx returned = new FunctionalList<>(this.wrapped.size()); forEach(element -> { // Add the transformed item to the result @@ -334,12 +334,12 @@ public class FunctionalList implements Cloneable, IList { } @Override - public IList> pairWith(final IList rightList) { - return combineWith(rightList, Pair::new); + public ListEx> pairWith(final ListEx rightList) { + return combineWith(rightList, SimplePair::new); } @Override - public IList> partition(final int numberPerPartition) { + public ListEx> 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"; @@ -348,10 +348,10 @@ public class FunctionalList implements Cloneable, IList { throw new IllegalArgumentException(msg); } - final IList> returned = new FunctionalList<>(); + final ListEx> returned = new FunctionalList<>(); /* The current partition being filled. */ - final IHolder> currentPartition = new Identity<>(new FunctionalList<>()); + final Holder> currentPartition = new Identity<>(new FunctionalList<>()); this.forEach(element -> { if (isPartitionFull(numberPerPartition, currentPartition)) { @@ -395,7 +395,7 @@ public class FunctionalList implements Cloneable, IList { } /* The current collapsed list. */ - final IHolder currentState = new Identity<>(initialValue); + final Holder currentState = new Identity<>(initialValue); wrapped.forEach(element -> { /* Accumulate a new value into the state. */ @@ -444,7 +444,7 @@ public class FunctionalList implements Cloneable, IList { } @Override - public IList tail() { + public ListEx tail() { return new FunctionalList<>(wrapped.subList(1, getSize())); } diff --git a/src/main/java/bjc/funcdata/FunctionalMap.java b/src/main/java/bjc/funcdata/FunctionalMap.java index 3ab2598..3427a91 100644 --- a/src/main/java/bjc/funcdata/FunctionalMap.java +++ b/src/main/java/bjc/funcdata/FunctionalMap.java @@ -6,7 +6,7 @@ import java.util.function.*; import bjc.data.*; /** - * Basic implementation of {@link IMap} + * Basic implementation of {@link MapEx} * * @author ben * @@ -16,7 +16,7 @@ import bjc.data.*; * @param * The type of the map's values. */ -public class FunctionalMap implements IMap { +public class FunctionalMap implements MapEx { /* Our backing store. */ private Map wrappedMap; @@ -35,10 +35,10 @@ public class FunctionalMap implements IMap... entries) { + public FunctionalMap(final Pair... entries) { this(); - for (final IPair entry : entries) { + for (final Pair entry : entries) { entry.doWith(wrappedMap::put); } } @@ -89,7 +89,7 @@ public class FunctionalMap implements IMap keyList() { + public ListEx keyList() { final FunctionalList keys = new FunctionalList<>(); wrappedMap.keySet().forEach(keys::add); diff --git a/src/main/java/bjc/funcdata/FunctionalStringTokenizer.java b/src/main/java/bjc/funcdata/FunctionalStringTokenizer.java index 856c153..3344e05 100644 --- a/src/main/java/bjc/funcdata/FunctionalStringTokenizer.java +++ b/src/main/java/bjc/funcdata/FunctionalStringTokenizer.java @@ -128,7 +128,7 @@ public class FunctionalStringTokenizer { * * @return This tokenizer, converted into a list of strings. */ - public IList toList() { + public ListEx toList() { return toList((final String element) -> element); } @@ -144,11 +144,11 @@ public class FunctionalStringTokenizer { * * @return A list containing all of the converted tokens. */ - public IList toList(final Function transformer) { + public ListEx toList(final Function transformer) { if (transformer == null) throw new NullPointerException("Transformer must not be null"); - final IList returned = new FunctionalList<>(); + final ListEx returned = new FunctionalList<>(); /* Add each token to the list after transforming it. */ forEachToken(token -> { diff --git a/src/main/java/bjc/funcdata/IFreezable.java b/src/main/java/bjc/funcdata/IFreezable.java deleted file mode 100644 index abc7d6f..0000000 --- a/src/main/java/bjc/funcdata/IFreezable.java +++ /dev/null @@ -1,73 +0,0 @@ -package bjc.funcdata; - -/** - * Indicates that an object can switch between immutable and mutable modes. - * - * Note that this only implements 'shallow' immutability. Namely, any sub-objects - * are not made immutable, and if the type is a collection, the elements are still - * as mutable as they were before. - * - * Implementations of this interface may choose to throw {@link ObjectFrozen} if - * you attempt to modify a frozen object, but they may also choose not to. - * - * @author Ben Culkin - */ -public interface IFreezable { - /** - * Freezes the internal state of this object, making it immutable. - * - * @return True if the object is frozen, false if it couldn't be frozen. - */ - public boolean freeze(); - /** - * Thaws the internal state of this object, making it mutable. - * - * @return True if the object is thawed, false if it couldn't be thawed. - */ - public boolean thaw(); - - /** - * 'Deep-freeze' this object, making it immutable and disabling the ability to - * thaw it. - * - * @return True if the object was deep-frozen, false if that couldn't happen. - */ - default boolean deepFreeze() { - return false; - } - - /** - * Check if this object can be frozen. - * - * @return Whether or not the object can be frozen. - */ - default boolean canFreeze() { - return false; - } - - /** - * Checks if this object can be thawed. - * - * @return Whether or not the object can be thawed. - */ - default boolean canThaw() { - return false; - } - - /** - * Determines if this object is frozen. - * - * @return True if the object is frozen, false if the object is thawed. - */ - public boolean isFrozen(); - - - /** - * Determines if this object is thawed. - * - * @return True if the object is thawed, false if the object is thawed. - */ - default boolean isThawed() { - return !isFrozen(); - } -} diff --git a/src/main/java/bjc/funcdata/IList.java b/src/main/java/bjc/funcdata/IList.java deleted file mode 100644 index 0ff8e30..0000000 --- a/src/main/java/bjc/funcdata/IList.java +++ /dev/null @@ -1,455 +0,0 @@ -package bjc.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.data.IPair; -import bjc.functypes.ID; - -/** - * A wrapper over another list that provides functional operations over it. - * - * @author ben - * - * @param - * The type in this list - */ -public interface IList extends Iterable { - /** - * 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 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 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 matcher); - - /** - * Reduce the contents of this list using a collector. - * - * @param - * The intermediate accumulation type. - * - * @param - * The final, reduced type. - * - * @param collector - * The collector to use for reduction. - * - * @return The reduced list. - */ - default ReducedType - collect(final Collector collector) { - final BiConsumer 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 - * The type of the second list. - * - * @param - * 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. - */ - IList combineWith(IList list, - BiFunction 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(); - - /** - * Get the last element in the list. - * - * @return The last element in this list. - */ - ContainedType last(); - - /** - * Remove and return the first element from the list. - * - * @return The first element from the list. - */ - ContainedType popFirst(); - - /** - * Remove and return the last element from the list. - * - * @return The last element from the list. - */ - ContainedType popLast(); - - /** - * Apply a function to each member of the list, then flatten the results. - * - * Does not change the underlying list. - * - * @param - * 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. - */ - IList - flatMap(Function> 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 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 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 getMatching(Predicate 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 - * 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. - */ - IList map(Function transformer); - - /** - * Zip two lists into a list of pairs. - * - * @param - * 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. - */ - IList> pairWith(IList 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 partitionSize. The last - * partition may not be completely full if the size of the list is not a - * multiple of partitionSize. - */ - IList> 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 rnd); - - /** - * Reduce this list to a single value, using a accumulative approach. - * - * @param - * The in-between type of the values - * - * @param - * 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. - */ - ReducedType reduceAux(StateType initial, - BiFunction accumulator, - Function transformer); - - /** - * Reduce this list to a single value, using a accumulative approach. - * - * @param - * 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 reduceAux(StateType initial, - BiFunction 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 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 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 comparator); - - /** - * Get the tail of this list (the list without the first element). - * - * @return The list without the first element. - */ - IList 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 toIterable(); - - @Override - default Iterator iterator() { - return toIterable().iterator(); - } -} diff --git a/src/main/java/bjc/funcdata/IMap.java b/src/main/java/bjc/funcdata/IMap.java deleted file mode 100644 index ca9ef11..0000000 --- a/src/main/java/bjc/funcdata/IMap.java +++ /dev/null @@ -1,216 +0,0 @@ -package bjc.funcdata; - -import java.util.*; -import java.util.function.*; - -/** - * Functional wrapper over map providing some useful things. - * - * @author ben - * - * @param - * The type of this map's keys. - * - * @param - * The type of this map's values. - */ -public interface IMap extends IFreezable { - /** - * Execute an action for each entry in the map. - * - * @param action - * The action to execute for each entry in the map. - */ - void forEach(BiConsumer 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 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 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. - */ - Optional get(KeyType key); - - /** - * 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() { - if (isFrozen()) throw new ObjectFrozen("Can't clear a frozen map"); - - keyList().forEach(IMap.this::remove); - } - - /** - * Get the number of entries in this map. - * - * @return The number of entries in this map. - */ - default int size() { - return keyList().getSize(); - } - - /** - * 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 keyList(); - - /** - * Get a list of the values in this map. - * - * @return A list of values in this map. - */ - default IList valueList() { - final IList returns = new FunctionalList<>(); - - for (final KeyType key : keyList()) { - returns.add(get(key).orElse(null)); - } - - return returns; - } - - /* - * @NOTE Do we want this to be the semantics for transform, or do we want to go - * to semantics using something like Isomorphism, or doing a one-time bulk - * conversion of the values? - */ - - /** - * 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 - * 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 IMap transform(final Function 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. - */ - default IMap extend() { - return extend(new FunctionalMap<>()); - }; - - - /** - * Extend this map, creating a new map that will delegate queries to - * the current map but store any added values in the provided map. - * - * @param backer The map to store values in. - * - * @return An extended map, with the specified backing map. - */ - default IMap extend(IMap backer) { - return new ExtendedMap<>(this, backer); - }; - - /** - * Static method to create a basic instance of IMap. - * - * @param The key type of the map. - * @param The value type of the map. - * - * @param args A series of key-value pairs. You will get an error if you don't - * provide the correct number of arguments (a number divisible by 2); - * however, if you pass arguments of the wrong type, you will not - * get a compile error, and usually won't get a runtime error in - * construction. However, you will get a ClassCastException as soon - * as you do something that attempts to iterate over the keys or values - * of the map. - * - * @return A map, constructed from the provided values. - * - * @throws IllegalArgumentException If you provide an incomplete pair of arguments. - */ - @SuppressWarnings("unchecked") - static IMap of(Object... args) { - if (args.length % 2 != 0) throw new IllegalArgumentException("Args must be in the form of key-value pairs"); - - IMap map = new FunctionalMap<>(); - for (int index = 0; index < args.length; index += 2) { - KeyType2 key = (KeyType2) args[index]; - ValueType2 value = (ValueType2) args[index + 1]; - - map.put(key, value); - } - - return map; - } -} diff --git a/src/main/java/bjc/funcdata/ListEx.java b/src/main/java/bjc/funcdata/ListEx.java new file mode 100644 index 0000000..164a71d --- /dev/null +++ b/src/main/java/bjc/funcdata/ListEx.java @@ -0,0 +1,455 @@ +package bjc.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.data.Pair; +import bjc.functypes.ID; + +/** + * A wrapper over another list that provides functional operations over it. + * + * @author ben + * + * @param + * The type in this list + */ +public interface ListEx extends Iterable { + /** + * 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 ListEx 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 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 matcher); + + /** + * Reduce the contents of this list using a collector. + * + * @param + * The intermediate accumulation type. + * + * @param + * The final, reduced type. + * + * @param collector + * The collector to use for reduction. + * + * @return The reduced list. + */ + default ReducedType + collect(final Collector collector) { + final BiConsumer 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 + * The type of the second list. + * + * @param + * 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. + */ + ListEx combineWith(ListEx list, + BiFunction 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(); + + /** + * Get the last element in the list. + * + * @return The last element in this list. + */ + ContainedType last(); + + /** + * Remove and return the first element from the list. + * + * @return The first element from the list. + */ + ContainedType popFirst(); + + /** + * Remove and return the last element from the list. + * + * @return The last element from the list. + */ + ContainedType popLast(); + + /** + * Apply a function to each member of the list, then flatten the results. + * + * Does not change the underlying list. + * + * @param + * 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. + */ + ListEx + flatMap(Function> 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 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 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. + */ + ListEx getMatching(Predicate 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 + * 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. + */ + ListEx map(Function transformer); + + /** + * Zip two lists into a list of pairs. + * + * @param + * 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. + */ + ListEx> pairWith(ListEx 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 partitionSize. The last + * partition may not be completely full if the size of the list is not a + * multiple of partitionSize. + */ + ListEx> 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 rnd); + + /** + * Reduce this list to a single value, using a accumulative approach. + * + * @param + * The in-between type of the values + * + * @param + * 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. + */ + ReducedType reduceAux(StateType initial, + BiFunction accumulator, + Function transformer); + + /** + * Reduce this list to a single value, using a accumulative approach. + * + * @param + * 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 reduceAux(StateType initial, + BiFunction 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 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 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 comparator); + + /** + * Get the tail of this list (the list without the first element). + * + * @return The list without the first element. + */ + ListEx 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 toIterable(); + + @Override + default Iterator iterator() { + return toIterable().iterator(); + } +} diff --git a/src/main/java/bjc/funcdata/MapEx.java b/src/main/java/bjc/funcdata/MapEx.java new file mode 100644 index 0000000..a7af4c5 --- /dev/null +++ b/src/main/java/bjc/funcdata/MapEx.java @@ -0,0 +1,216 @@ +package bjc.funcdata; + +import java.util.*; +import java.util.function.*; + +/** + * Functional wrapper over map providing some useful things. + * + * @author ben + * + * @param + * The type of this map's keys. + * + * @param + * The type of this map's values. + */ +public interface MapEx extends Freezable { + /** + * Execute an action for each entry in the map. + * + * @param action + * The action to execute for each entry in the map. + */ + void forEach(BiConsumer 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 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 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. + */ + Optional get(KeyType key); + + /** + * 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() { + if (isFrozen()) throw new ObjectFrozen("Can't clear a frozen map"); + + keyList().forEach(MapEx.this::remove); + } + + /** + * Get the number of entries in this map. + * + * @return The number of entries in this map. + */ + default int size() { + return keyList().getSize(); + } + + /** + * 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. + */ + ListEx keyList(); + + /** + * Get a list of the values in this map. + * + * @return A list of values in this map. + */ + default ListEx valueList() { + final ListEx returns = new FunctionalList<>(); + + for (final KeyType key : keyList()) { + returns.add(get(key).orElse(null)); + } + + return returns; + } + + /* + * @NOTE Do we want this to be the semantics for transform, or do we want to go + * to semantics using something like Isomorphism, or doing a one-time bulk + * conversion of the values? + */ + + /** + * 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 + * 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 MapEx transform(final Function 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. + */ + default MapEx extend() { + return extend(new FunctionalMap<>()); + }; + + + /** + * Extend this map, creating a new map that will delegate queries to + * the current map but store any added values in the provided map. + * + * @param backer The map to store values in. + * + * @return An extended map, with the specified backing map. + */ + default MapEx extend(MapEx backer) { + return new ExtendedMap<>(this, backer); + }; + + /** + * Static method to create a basic instance of IMap. + * + * @param The key type of the map. + * @param The value type of the map. + * + * @param args A series of key-value pairs. You will get an error if you don't + * provide the correct number of arguments (a number divisible by 2); + * however, if you pass arguments of the wrong type, you will not + * get a compile error, and usually won't get a runtime error in + * construction. However, you will get a ClassCastException as soon + * as you do something that attempts to iterate over the keys or values + * of the map. + * + * @return A map, constructed from the provided values. + * + * @throws IllegalArgumentException If you provide an incomplete pair of arguments. + */ + @SuppressWarnings("unchecked") + static MapEx of(Object... args) { + if (args.length % 2 != 0) throw new IllegalArgumentException("Args must be in the form of key-value pairs"); + + MapEx map = new FunctionalMap<>(); + for (int index = 0; index < args.length; index += 2) { + KeyType2 key = (KeyType2) args[index]; + ValueType2 value = (ValueType2) args[index + 1]; + + map.put(key, value); + } + + return map; + } +} diff --git a/src/main/java/bjc/funcdata/ObjectFrozen.java b/src/main/java/bjc/funcdata/ObjectFrozen.java index 2260a0e..a9f58b8 100644 --- a/src/main/java/bjc/funcdata/ObjectFrozen.java +++ b/src/main/java/bjc/funcdata/ObjectFrozen.java @@ -1,7 +1,7 @@ package bjc.funcdata; /** - * Exception that implementations of {@link IFreezable} can throw if you attempt + * Exception that implementations of {@link Freezable} can throw if you attempt * to modify a frozen object. * * @author Ben Culkin diff --git a/src/main/java/bjc/funcdata/TransformedValueMap.java b/src/main/java/bjc/funcdata/TransformedValueMap.java index 1e0ef51..643f610 100644 --- a/src/main/java/bjc/funcdata/TransformedValueMap.java +++ b/src/main/java/bjc/funcdata/TransformedValueMap.java @@ -19,9 +19,9 @@ import java.util.function.*; * */ final class TransformedValueMap - implements IMap { + implements MapEx { /* Our backing map. */ - private final IMap backing; + private final MapEx backing; /* Our transforming function. */ private final Function transformer; @@ -37,7 +37,7 @@ final class TransformedValueMap * @param transform * The function to use for the transform. */ - public TransformedValueMap(final IMap backingMap, + public TransformedValueMap(final MapEx backingMap, final Function transform) { backing = backingMap; transformer = transform; @@ -73,7 +73,7 @@ final class TransformedValueMap } @Override - public IList keyList() { + public ListEx keyList() { return backing.keyList(); } diff --git a/src/main/java/bjc/funcdata/bst/BinarySearchTree.java b/src/main/java/bjc/funcdata/bst/BinarySearchTree.java index 2c5b4d8..99b67cd 100644 --- a/src/main/java/bjc/funcdata/bst/BinarySearchTree.java +++ b/src/main/java/bjc/funcdata/bst/BinarySearchTree.java @@ -6,7 +6,7 @@ import java.util.List; import java.util.function.Predicate; import bjc.funcdata.FunctionalList; -import bjc.funcdata.IList; +import bjc.funcdata.ListEx; /** * A binary search tree, with some mild support for functional traversal. @@ -24,7 +24,7 @@ public class BinarySearchTree { private int elementCount; /* The root element of the tree */ - private ITreePart root; + private TreePart root; /** * Create a new tree using the specified way to compare elements. @@ -66,7 +66,7 @@ public class BinarySearchTree { * * @return Whether the adjusted pivot is with the list. */ - private boolean adjustedPivotInBounds(final IList elements, final int pivot, + private boolean adjustedPivotInBounds(final ListEx elements, final int pivot, final int pivotAdjustment) { return ((pivot - pivotAdjustment) >= 0) && ((pivot + pivotAdjustment) < elements.getSize()); @@ -78,7 +78,7 @@ public class BinarySearchTree { * Takes O(N) time, but also O(N) space. */ public void balance() { - final IList elements = new FunctionalList<>(); + final ListEx elements = new FunctionalList<>(); /* Add each element to the list in sorted order. */ root.forEach(TreeLinearizationMethod.INORDER, element -> elements.add(element)); @@ -135,7 +135,7 @@ public class BinarySearchTree { * * @return The root of the tree. */ - public ITreePart getRoot() { + public TreePart getRoot() { return root; } diff --git a/src/main/java/bjc/funcdata/bst/BinarySearchTreeLeaf.java b/src/main/java/bjc/funcdata/bst/BinarySearchTreeLeaf.java index 0b99cad..9532555 100644 --- a/src/main/java/bjc/funcdata/bst/BinarySearchTreeLeaf.java +++ b/src/main/java/bjc/funcdata/bst/BinarySearchTreeLeaf.java @@ -13,7 +13,7 @@ import java.util.function.Predicate; * @param * The data stored in the tree. */ -public class BinarySearchTreeLeaf implements ITreePart { +public class BinarySearchTreeLeaf implements TreePart { /** The data held in this tree leaf */ protected T data; diff --git a/src/main/java/bjc/funcdata/bst/BinarySearchTreeNode.java b/src/main/java/bjc/funcdata/bst/BinarySearchTreeNode.java index a73f81a..0eef92a 100644 --- a/src/main/java/bjc/funcdata/bst/BinarySearchTreeNode.java +++ b/src/main/java/bjc/funcdata/bst/BinarySearchTreeNode.java @@ -20,10 +20,10 @@ import java.util.function.Predicate; */ public class BinarySearchTreeNode extends BinarySearchTreeLeaf { /* The left child of this node */ - private ITreePart left; + private TreePart left; /* The right child of this node */ - private ITreePart right; + private TreePart right; /** * Create a new node with the specified data and children. @@ -37,8 +37,8 @@ public class BinarySearchTreeNode extends BinarySearchTreeLeaf { * @param rght * The right child of this node. */ - public BinarySearchTreeNode(final T element, final ITreePart lft, - final ITreePart rght) { + public BinarySearchTreeNode(final T element, final TreePart lft, + final TreePart rght) { super(element); this.left = lft; this.right = rght; diff --git a/src/main/java/bjc/funcdata/bst/ITreePart.java b/src/main/java/bjc/funcdata/bst/ITreePart.java deleted file mode 100644 index bac640d..0000000 --- a/src/main/java/bjc/funcdata/bst/ITreePart.java +++ /dev/null @@ -1,107 +0,0 @@ -package bjc.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 - * The data contained in this part of the tree. - */ -public interface ITreePart { - /** - * 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 comparator); - - /** - * Collapses this tree part into a single value. - * - * Does not change the underlying tree. - * - * @param - * 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 collapse(Function nodeCollapser, - BiFunction 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 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 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 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 predicate); -} diff --git a/src/main/java/bjc/funcdata/bst/TreePart.java b/src/main/java/bjc/funcdata/bst/TreePart.java new file mode 100644 index 0000000..b451463 --- /dev/null +++ b/src/main/java/bjc/funcdata/bst/TreePart.java @@ -0,0 +1,107 @@ +package bjc.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 + * The data contained in this part of the tree. + */ +public interface TreePart { + /** + * 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 comparator); + + /** + * Collapses this tree part into a single value. + * + * Does not change the underlying tree. + * + * @param + * 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 collapse(Function nodeCollapser, + BiFunction 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 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 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 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 predicate); +} -- cgit v1.2.3