From 8923edffdb36b790014ff47301e53f7ede93ea0d Mon Sep 17 00:00:00 2001 From: "Benjamin J. Culkin" Date: Wed, 11 Oct 2017 22:49:16 -0300 Subject: Cleanup more --- .../utils/funcdata/FunctionalStringTokenizer.java | 75 +++--- base/src/main/java/bjc/utils/funcdata/IList.java | 251 ++++++++++++--------- base/src/main/java/bjc/utils/funcdata/IMap.java | 82 ++++--- .../main/java/bjc/utils/funcdata/SentryList.java | 8 +- .../bjc/utils/funcdata/TransformedValueMap.java | 26 ++- base/src/main/java/bjc/utils/functypes/ID.java | 4 +- .../java/bjc/utils/functypes/ListFlattener.java | 2 +- .../java/bjc/utils/funcutils/CollectorUtils.java | 27 ++- .../bjc/utils/funcutils/CompoundCollector.java | 33 ++- .../main/java/bjc/utils/funcutils/EnumUtils.java | 33 +-- .../main/java/bjc/utils/funcutils/FileUtils.java | 31 +-- .../main/java/bjc/utils/funcutils/FuncUtils.java | 33 +-- .../bjc/utils/funcutils/FunctionalFileVisitor.java | 15 +- .../bjc/utils/funcutils/GroupPartIteration.java | 38 +++- .../main/java/bjc/utils/funcutils/IBuilder.java | 18 +- .../main/java/bjc/utils/funcutils/Isomorphism.java | 23 +- .../main/java/bjc/utils/funcutils/LambdaLock.java | 30 +-- .../main/java/bjc/utils/funcutils/ListUtils.java | 166 +++++++------- .../main/java/bjc/utils/funcutils/NumberUtils.java | 42 ++-- .../main/java/bjc/utils/funcutils/StringUtils.java | 105 +++++---- .../main/java/bjc/utils/funcutils/TreeUtils.java | 9 +- .../main/java/bjc/utils/funcutils/TriConsumer.java | 15 +- .../src/main/java/bjc/utils/gen/RandomGrammar.java | 21 +- .../main/java/bjc/utils/gen/WeightedGrammar.java | 247 +++++++++++--------- .../main/java/bjc/utils/gen/WeightedRandom.java | 39 ++-- .../main/java/bjc/utils/graph/AdjacencyMap.java | 77 ++++--- base/src/main/java/bjc/utils/graph/Edge.java | 50 ++-- base/src/main/java/bjc/utils/graph/Graph.java | 160 +++++++------ 28 files changed, 965 insertions(+), 695 deletions(-) (limited to 'base/src/main/java/bjc') diff --git a/base/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java b/base/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java index e068b46..384572d 100644 --- a/base/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java +++ b/base/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java @@ -5,18 +5,19 @@ import java.util.function.Consumer; import java.util.function.Function; /** - * A string tokenizer that exposes a functional interface + * 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. + * 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"); @@ -24,16 +25,14 @@ public class FunctionalStringTokenizer { return new FunctionalStringTokenizer(new StringTokenizer(strang, " ")); } - /* - * The string tokenizer being driven - */ + /* The string tokenizer being driven */ private final StringTokenizer input; /** - * Create a functional string tokenizer from a given string + * Create a functional string tokenizer from a given string. * * @param inp - * The string to tokenize + * The string to tokenize. */ public FunctionalStringTokenizer(final String inp) { if (inp == null) throw new NullPointerException("String to tokenize must be non-null"); @@ -43,26 +42,29 @@ public class FunctionalStringTokenizer { /** * Create a functional string tokenizer from a given string and set of - * separators + * separators. * * @param input - * The string to tokenize + * The string to tokenize. + * * @param seperators - * The set of separating tokens to use for splitting + * The set of separating tokens to use for splitting. */ public FunctionalStringTokenizer(final String input, final String seperators) { - if (input == null) + 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"); + } 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 + * Create a functional string tokenizer from a non-functional one. * * @param toWrap - * The non-functional string tokenizer to wrap + * The non-functional string tokenizer to wrap. */ public FunctionalStringTokenizer(final StringTokenizer toWrap) { if (toWrap == null) throw new NullPointerException("Wrapped tokenizer must not be null"); @@ -71,10 +73,10 @@ public class FunctionalStringTokenizer { } /** - * Execute a provided action for each of the remaining tokens + * Execute a provided action for each of the remaining tokens. * * @param action - * The action to execute for each token + * The action to execute for each token. */ public void forEachToken(final Consumer action) { if (action == null) throw new NullPointerException("Action must not be null"); @@ -85,18 +87,20 @@ public class FunctionalStringTokenizer { } /** - * Get the string tokenizer encapsulated by this tokenizer + * Get the string tokenizer encapsulated by this tokenizer. * - * @return The encapsulated tokenizer + * @return + * The encapsulated tokenizer. */ public StringTokenizer getInternal() { return input; } /** - * Check if this tokenizer has more tokens + * Check if this tokenizer has more tokens. * - * @return Whether or not this tokenizer has more tokens + * @return + * Whether or not this tokenizer has more tokens. */ public boolean hasMoreTokens() { return input.hasMoreTokens(); @@ -105,22 +109,25 @@ public class FunctionalStringTokenizer { /** * Return the next token from the tokenizer. * - * Returns null if no more tokens are available - * - * @return The next token from the tokenizer + * @return + * The next token from the tokenizer, or null if no more tokens are + * available. */ public String nextToken() { - if (input.hasMoreTokens()) // Return the next available token + if (input.hasMoreTokens()) { + /* Return the next available token. */ return input.nextToken(); + } - // Return no token + /* Return no token. */ return null; } /** - * Convert this tokenizer into a list of strings + * Convert this tokenizer into a list of strings. * - * @return This tokenizer, converted into a list of strings + * @return + * This tokenizer, converted into a list of strings. */ public IList toList() { return toList((final String element) -> element); @@ -131,18 +138,20 @@ public class FunctionalStringTokenizer { * the input from this tokenizer. * * @param - * The type of the converted tokens + * The type of the converted tokens. * * @param transformer - * The function to use to convert tokens. - * @return A list containing all of the converted tokens. + * The function to use to convert tokens. + * + * @return + * A list containing all of the converted tokens. */ public IList toList(final Function transformer) { if (transformer == null) throw new NullPointerException("Transformer must not be null"); final IList returned = new FunctionalList<>(); - // Add each token to the list after transforming it + /* Add each token to the list after transforming it. */ forEachToken(token -> { final E transformedToken = transformer.apply(token); diff --git a/base/src/main/java/bjc/utils/funcdata/IList.java b/base/src/main/java/bjc/utils/funcdata/IList.java index 28c09d0..4dd2b1a 100644 --- a/base/src/main/java/bjc/utils/funcdata/IList.java +++ b/base/src/main/java/bjc/utils/funcdata/IList.java @@ -18,25 +18,28 @@ import bjc.utils.functypes.ID; * @author ben * * @param - * The type in this list + * The type in this list */ public interface IList extends Iterable { /** - * Add an item to this list + * 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. + * 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 + * 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 + * 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); @@ -46,10 +49,11 @@ public interface IList extends Iterable { * Add all of the elements in the provided array to this list. * * @param items - * The array of items to add. + * The array of items to add. * - * @return True if every item was successfully added to the list, false - * otherwise. + * @return + * True if every item was successfully added to the list, false + * otherwise. */ @SuppressWarnings("unchecked") default boolean addAll(final ContainedType... items) { @@ -69,9 +73,11 @@ public interface IList extends Iterable { * predicate. * * @param matcher - * The predicate to use for checking. - * @return Whether all of the elements of the list match the specified - * predicate. + * The predicate to use for checking. + * + * @return + * Whether all of the elements of the list match the specified + * predicate. */ boolean allMatch(Predicate matcher); @@ -79,22 +85,27 @@ public interface IList extends Iterable { * 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. + * 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 + * Reduce the contents of this list using a collector. * * @param - * The intermediate accumulation type + * The intermediate accumulation type. + * * @param - * The final, reduced type + * The final, reduced type. + * * @param collector - * The collector to use for reduction - * @return The reduced list + * The collector to use for reduction. + * + * @return + * The reduced list. */ default ReducedType collect( final Collector collector) { @@ -119,32 +130,39 @@ public interface IList extends Iterable { * list and the combined one. * * @param - * The type of the second list + * The type of the second list. + * * @param - * The type of the combined list + * The type of the combined list. * * @param list - * The list to combine with + * 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. + * 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 + * 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 + * 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 + * Get the first element in the list. * - * @return The first element in this list. + * @return + * The first element in this list. */ ContainedType first(); @@ -155,20 +173,22 @@ public interface IList extends Iterable { * Does not change the underlying list. * * @param - * The type of the flattened list + * 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. + * 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 + * Apply a given action for each member of the list. * * @param action - * The action to apply to each member of the list. + * The action to apply to each member of the list. */ @Override void forEach(Consumer action); @@ -177,8 +197,7 @@ public interface IList extends Iterable { * 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. + * The function to apply to each element in the list and its index. */ void forEachIndexed(BiConsumer action); @@ -186,31 +205,37 @@ public interface IList extends Iterable { * 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. + * 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 + * 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 + * 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 + * Retrieve the size of the wrapped list. * - * @return 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. + * @return + * Whether or not this list is empty. */ boolean isEmpty(); @@ -221,42 +246,48 @@ public interface IList extends Iterable { * Does not change the underlying list. * * @param - * The type of the transformed list + * 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. + * 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 + * Zip two lists into a list of pairs. * * @param - * The type of the second list + * 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 + * 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 + * 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 + * 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 + * Prepend an item to the list. * * @param item - * The item to prepend to the list + * The item to prepend to the list. */ void prepend(ContainedType item); @@ -264,7 +295,7 @@ public interface IList extends Iterable { * Prepend an array of items to the list. * * @param items - * The items to prepend to the list. + * The items to prepend to the list. */ @SuppressWarnings("unchecked") default void prependAll(final ContainedType... items) { @@ -275,9 +306,10 @@ public interface IList extends Iterable { /** * Select a random item from the list, using a default random number - * generator + * generator. * - * @return A random item from the list + * @return + * A random item from the list */ default ContainedType randItem() { return randItem(num -> (int) (Math.random() * num)); @@ -288,8 +320,10 @@ public interface IList extends Iterable { * generator. * * @param rnd - * The random number generator to use. - * @return A random element from this list. + * The random number generator to use. + * + * @return + * A random element from this list. */ ContainedType randItem(Function rnd); @@ -297,20 +331,25 @@ public interface IList extends Iterable { * Reduce this list to a single value, using a accumulative approach. * * @param - * The in-between type of the values + * The in-between type of the values + * * @param - * The final value type + * The final value type * * @param initial - * The initial value of the accumulative state. + * The initial value of the accumulative state. + * * @param accumulator - * The function to use to combine a list element with the - * accumulative state. + * 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. + * 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, @@ -320,16 +359,17 @@ public interface IList extends Iterable { * Reduce this list to a single value, using a accumulative approach. * * @param - * The in-between type of the values. + * The in-between type of the values. * * @param initial - * The initial value of the accumulative state. + * The initial value of the accumulative state. * * @param accumulator - * The function to use to combine a list element with the - * accumulative state. + * The function to use to combine a list element with the + * accumulative state. * - * @return A single value condensed from this list. + * @return + * A single value condensed from this list. */ default StateType reduceAux(StateType initial, BiFunction accumulator) { @@ -337,25 +377,25 @@ public interface IList extends Iterable { } /** - * Remove all elements that match a given predicate + * 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 + * 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 + * Remove all parameters that match a given parameter. * * @param element - * The object to remove all matching copies of + * The object to remove all matching copies of. */ void removeMatching(ContainedType element); - /** - * Reverse the contents of this list in place - */ + /** Reverse the contents of this list in place. */ void reverse(); /** @@ -366,11 +406,14 @@ public interface IList extends Iterable { * hand. * * @param key - * The key to search for. + * 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. + * 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); @@ -381,31 +424,35 @@ public interface IList extends Iterable { * Does change the underlying list. * * @param comparator - * The way to compare elements for sorting. Pass null to - * use E's natural ordering + * 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 + * Get the tail of this list (the list without the first element). * - * @return The list without the first element + * @return + * The list without the first element. */ IList tail(); /** - * Convert this list into an array + * Convert this list into an array. * * @param type - * The type of array to return - * @return The list, as an array + * The type of array to return. + * + * @return + * The list, as an array. */ ContainedType[] toArray(ContainedType[] type); /** - * Convert the list into a Iterable + * Convert the list into a Iterable. * - * @return An iterable view onto the list + * @return + * An iterable view onto the list. */ Iterable toIterable(); diff --git a/base/src/main/java/bjc/utils/funcdata/IMap.java b/base/src/main/java/bjc/utils/funcdata/IMap.java index 0ee7375..0262c13 100644 --- a/base/src/main/java/bjc/utils/funcdata/IMap.java +++ b/base/src/main/java/bjc/utils/funcdata/IMap.java @@ -10,17 +10,17 @@ import java.util.function.Function; * @author ben * * @param - * The type of this map's keys. + * The type of this map's keys. * * @param - * The type of this map's values. + * The type of this map's values. */ public interface IMap { /** * Execute an action for each entry in the map. * * @param action - * the action to execute for each entry in the map. + * The action to execute for each entry in the map. */ void forEach(BiConsumer action); @@ -28,7 +28,7 @@ public interface IMap { * Perform an action for each key in the map. * * @param action - * The action to perform on each key in the map. + * The action to perform on each key in the map. */ default void forEachKey(final Consumer action) { forEach((key, val) -> action.accept(key)); @@ -38,7 +38,7 @@ public interface IMap { * Perform an action for each value in the map. * * @param action - * The action to perform on each value in the map. + * The action to perform on each value in the map. */ default void forEachValue(final Consumer action) { forEach((key, val) -> action.accept(val)); @@ -48,9 +48,10 @@ public interface IMap { * Check if this map contains the specified key. * * @param key - * The key to check. + * The key to check. * - * @return Whether or not the map contains the key. + * @return + * Whether or not the map contains the key. */ boolean containsKey(KeyType key); @@ -58,9 +59,10 @@ public interface IMap { * Get the value assigned to the given key. * * @param key - * The key to look for a value under. + * The key to look for a value under. * - * @return The value of the key. + * @return + * The value of the key. */ ValueType get(KeyType key); @@ -69,13 +71,14 @@ public interface IMap { * doesn't exist. * * @param key - * The key to attempt to retrieve. + * The key to attempt to retrieve. * * @param defaultValue - * The value to return if the key doesn't exist. + * 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. + * @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 { @@ -93,24 +96,22 @@ public interface IMap { * Add an entry to the map. * * @param key - * The key to put the value under. + * The key to put the value under. * * @param val - * The value to add. + * 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. + * @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 + * If the map implementation doesn't support modifying the map. */ ValueType put(KeyType key, ValueType val); - /** - * Delete all the values in the map. - */ + /** Delete all the values in the map. */ default void clear() { keyList().forEach(key -> remove(key)); } @@ -118,12 +119,18 @@ public interface IMap { /** * Get the number of entries in this map. * - * @return The number of entries in this map. + * @return + * The number of entries in this map. */ default int size() { return keyList().getSize(); } + /* @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. * @@ -132,12 +139,13 @@ public interface IMap { * likely not work as expected. * * @param - * The new type of returned values. + * The new type of returned values. * * @param transformer - * The function to use to transform values. + * The function to use to transform values. * - * @return The map where each value will be transformed after lookup. + * @return + * The map where each value will be transformed after lookup. */ default IMap transform(final Function transformer) { return new TransformedValueMap<>(this, transformer); @@ -147,7 +155,8 @@ public interface IMap { * Extends this map, creating a new map that will delegate queries to * the map, but store any added values itself. * - * @return An extended map. + * @return + * An extended map. */ IMap extend(); @@ -155,26 +164,29 @@ public interface IMap { * Remove the value bound to the key. * * @param key - * The key to remove from the map. + * 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. + * @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. + * @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. + * @return + * A list of values in this map. */ default IList valueList() { final IList returns = new FunctionalList<>(); diff --git a/base/src/main/java/bjc/utils/funcdata/SentryList.java b/base/src/main/java/bjc/utils/funcdata/SentryList.java index c322743..1040328 100644 --- a/base/src/main/java/bjc/utils/funcdata/SentryList.java +++ b/base/src/main/java/bjc/utils/funcdata/SentryList.java @@ -8,12 +8,10 @@ import java.util.List; * @author bjculkin * * @param - * The type of item in the list. + * The type of item in the list. */ public class SentryList extends FunctionalList { - /** - * Create a new sentry list. - */ + /** Create a new sentry list. */ public SentryList() { super(); } @@ -22,7 +20,7 @@ public class SentryList extends FunctionalList { * Create a new sentry list backed by an existing list. * * @param backing - * The backing list. + * The backing list. */ public SentryList(final List backing) { super(backing); diff --git a/base/src/main/java/bjc/utils/funcdata/TransformedValueMap.java b/base/src/main/java/bjc/utils/funcdata/TransformedValueMap.java index 0ca1fdc..a8cb762 100644 --- a/base/src/main/java/bjc/utils/funcdata/TransformedValueMap.java +++ b/base/src/main/java/bjc/utils/funcdata/TransformedValueMap.java @@ -10,16 +10,30 @@ import java.util.function.Function; * @author ben * * @param - * The type of the map's keys + * The type of the map's keys + * * @param - * The type of the map's values + * The type of the map's values + * * @param - * The type of the transformed values + * The type of the transformed values + * */ final class TransformedValueMap implements IMap { - private final IMap backing; - private final Function transformer; - + /* Our backing map. */ + private final IMap backing; + /* Our transforming function. */ + private final Function transformer; + + /** + * Create a new transformed-value loop. + * + * @param backingMap + * The map to use as backing. + * + * @param transform + * The function to use for the transform. + */ public TransformedValueMap(final IMap backingMap, final Function transform) { backing = backingMap; diff --git a/base/src/main/java/bjc/utils/functypes/ID.java b/base/src/main/java/bjc/utils/functypes/ID.java index d3197e2..4090410 100644 --- a/base/src/main/java/bjc/utils/functypes/ID.java +++ b/base/src/main/java/bjc/utils/functypes/ID.java @@ -6,13 +6,13 @@ import java.util.function.UnaryOperator; * Identity function. * * @author bjculkin - * */ public class ID { /** * Create an identity function. * - * @return A identity function. + * @return + * A identity function. */ public static UnaryOperator id() { return (x) -> x; diff --git a/base/src/main/java/bjc/utils/functypes/ListFlattener.java b/base/src/main/java/bjc/utils/functypes/ListFlattener.java index cfa0c8b..7d0ef63 100644 --- a/base/src/main/java/bjc/utils/functypes/ListFlattener.java +++ b/base/src/main/java/bjc/utils/functypes/ListFlattener.java @@ -10,7 +10,7 @@ import bjc.utils.funcdata.IList; * @author bjculkin * * @param - * The type of value in the list. + * The type of value in the list. */ public interface ListFlattener extends Function, S> { diff --git a/base/src/main/java/bjc/utils/funcutils/CollectorUtils.java b/base/src/main/java/bjc/utils/funcutils/CollectorUtils.java index a044bfd..2da5967 100644 --- a/base/src/main/java/bjc/utils/funcutils/CollectorUtils.java +++ b/base/src/main/java/bjc/utils/funcutils/CollectorUtils.java @@ -9,27 +9,34 @@ import bjc.utils.data.IPair; * Utilities for producing implementations of {@link Collector} * * @author ben - * */ public class CollectorUtils { /** - * Create a collector that applies two collectors at once + * Create a collector that applies two collectors at once. * * @param - * The type of the collection to collect from + * The type of the collection to collect from. + * * @param - * The intermediate type of the first collector + * The intermediate type of the first collector. + * * @param - * The intermediate type of the second collector + * The intermediate type of the second collector. + * * @param - * The final type of the first collector + * The final type of the first collector. + * * @param - * The final type of the second collector + * The final type of the second collector. + * * @param first - * The first collector to use + * The first collector to use. + * * @param second - * The second collector to use - * @return A collector that functions as mentioned above + * The second collector to use. + * + * @return + * A collector that functions as mentioned above. */ public static Collector>, IPair> compoundCollect( final Collector first, diff --git a/base/src/main/java/bjc/utils/funcutils/CompoundCollector.java b/base/src/main/java/bjc/utils/funcutils/CompoundCollector.java index 35695bc..928c3f4 100644 --- a/base/src/main/java/bjc/utils/funcutils/CompoundCollector.java +++ b/base/src/main/java/bjc/utils/funcutils/CompoundCollector.java @@ -12,26 +12,43 @@ import bjc.utils.data.IPair; import bjc.utils.data.Identity; import bjc.utils.data.Pair; +/** + * Implementation of a collecter that uses two collectors. + * + * @author Ben Culkin + */ final class CompoundCollector implements Collector>, IPair> { - + /* Our characteristics. */ private final Set characteristicSet; - private final Collector first; - private final Collector second; - + /* The first collector. */ + private final Collector first; + /* The second collector. */ + private final Collector second; + + /** + * Create a collector that uses two collectors. + * + * @param first + * The first collector. + * + * @param second + * The second collector. + */ public CompoundCollector(final Collector first, final Collector second) { this.first = first; this.second = second; + /* Accumulate characteristics. */ characteristicSet = first.characteristics(); characteristicSet.addAll(second.characteristics()); } @Override public BiConsumer>, InitialType> accumulator() { - final BiConsumer firstAccumulator = first.accumulator(); + final BiConsumer firstAccumulator = first.accumulator(); final BiConsumer secondAccumulator = second.accumulator(); return (state, value) -> { @@ -51,7 +68,7 @@ final class CompoundCollector>> combiner() { - final BinaryOperator firstCombiner = first.combiner(); + final BinaryOperator firstCombiner = first.combiner(); final BinaryOperator secondCombiner = second.combiner(); return (leftState, rightState) -> { @@ -68,7 +85,7 @@ final class CompoundCollector { return state.unwrap(pair -> { return pair.bind((left, right) -> { - final FinalType1 finalLeft = first.finisher().apply(left); + final FinalType1 finalLeft = first.finisher().apply(left); final FinalType2 finalRight = second.finisher().apply(right); return new Pair<>(finalLeft, finalRight); @@ -80,7 +97,7 @@ final class CompoundCollector>> supplier() { return () -> { - final AuxType1 initialLeft = first.supplier().get(); + final AuxType1 initialLeft = first.supplier().get(); final AuxType2 initialRight = second.supplier().get(); return new Identity<>(new Pair<>(initialLeft, initialRight)); diff --git a/base/src/main/java/bjc/utils/funcutils/EnumUtils.java b/base/src/main/java/bjc/utils/funcutils/EnumUtils.java index e4c0bda..2039b97 100644 --- a/base/src/main/java/bjc/utils/funcutils/EnumUtils.java +++ b/base/src/main/java/bjc/utils/funcutils/EnumUtils.java @@ -7,25 +7,28 @@ import bjc.utils.funcdata.FunctionalList; import bjc.utils.funcdata.IList; /** - * Utility methods on enums + * Utility methods on enums. * * @author ben - * */ public class EnumUtils { /** - * Do an action for a random number of enum values + * Do an action for a random number of enum values. * * @param - * The type of the enum + * The type of the enum. + * * @param clasz - * The enum class + * The enum class. + * * @param nValues - * The number of values to execute the action on + * The number of values to execute the action on. + * * @param action - * The action to perform on random values + * The action to perform on random values. + * * @param rnd - * The source of randomness to use + * The source of randomness to use. */ public static > void doForValues(final Class clasz, final int nValues, final Consumer action, final Random rnd) { @@ -45,15 +48,19 @@ public class EnumUtils { } /** - * Get a random value from an enum + * Get a random value from an enum. * * @param - * The type of the enum + * The type of the enum. + * * @param clasz - * The class of the enum + * The class of the enum. + * * @param rnd - * The random source to use - * @return A random value from the specified enum + * The random source to use. + * + * @return + * A random value from the specified enum. */ public static > E getRandomValue(final Class clasz, final Random rnd) { final E[] enumValues = clasz.getEnumConstants(); diff --git a/base/src/main/java/bjc/utils/funcutils/FileUtils.java b/base/src/main/java/bjc/utils/funcutils/FileUtils.java index 87199b1..6b897df 100644 --- a/base/src/main/java/bjc/utils/funcutils/FileUtils.java +++ b/base/src/main/java/bjc/utils/funcutils/FileUtils.java @@ -7,31 +7,34 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.function.BiPredicate; /** - * Utilities for doing things with files + * Utilities for doing things with files. * * @author ben - * */ public class FileUtils { + /* + * @NOTE + * If it becomes necessary, write another overload + * for this with all the buttons and knobs from + * walkFileTree. + */ /** - * Traverse a directory recursively. This is a depth-first traversal - * + * Traverse a directory recursively. This is a depth-first traversal. * * @param root - * The directory to start the traversal at + * The directory to start the traversal at. + * * @param predicate - * The predicate to determine whether or not to traverse - * a directory + * The predicate to determine whether or not to traverse + * a directory. + * * @param action - * The action to invoke upon each file in the directory. - * Returning true means to continue the traversal, - * returning false stops it + * The action to invoke upon each file in the directory. Returning + * true means to continue the traversal, returning false stops it. + * * @throws IOException - * if the walk throws an exception + * If the walk throws an exception. * - * TODO If it becomes necessary, write another overload - * for this with all the buttons and knobs from - * walkFileTree */ public static void traverseDirectory(final Path root, final BiPredicate predicate, final BiPredicate action) throws IOException { diff --git a/base/src/main/java/bjc/utils/funcutils/FuncUtils.java b/base/src/main/java/bjc/utils/funcutils/FuncUtils.java index 9950add..4be6d78 100644 --- a/base/src/main/java/bjc/utils/funcutils/FuncUtils.java +++ b/base/src/main/java/bjc/utils/funcutils/FuncUtils.java @@ -6,26 +6,29 @@ import java.util.function.Function; import java.util.function.UnaryOperator; /** - * Utility things for functions + * Utility things for functions. * * @author ben - * */ public class FuncUtils { /** * Convert a binary function into a unary function that returns a - * function + * function. * * @param - * The initial type of the function + * The initial type of the function. + * * @param - * The intermediate type of the function + * The intermediate type of the function. + * * @param - * The terminal type of the function + * The terminal type of the function. + * * @param func - * The function to transform - * @return The function transformed into a unary function returning a - * function + * The function to transform. + * + * @return + * The function transformed into a unary function returning a function. */ public static Function> curry2(final BiFunction func) { return arg1 -> arg2 -> { @@ -34,12 +37,13 @@ public class FuncUtils { } /** - * Do the specified action the specified number of times + * Do the specified action the specified number of times. * * @param nTimes - * The number of times to do the action + * The number of times to do the action. + * * @param cons - * The action to perform + * The action to perform. */ public static void doTimes(final int nTimes, final Consumer cons) { for (int i = 0; i < nTimes; i++) { @@ -52,9 +56,10 @@ public class FuncUtils { * * @param op * The operator to execute. + * * @param maxTries - * The maximum amount of times to apply the function in an - * attempt to cause it to converge. + * The maximum amount of times to apply the function in an attempt + * to cause it to converge. */ public static UnaryOperator converge(final UnaryOperator op, final int maxTries) { return (val) -> { diff --git a/base/src/main/java/bjc/utils/funcutils/FunctionalFileVisitor.java b/base/src/main/java/bjc/utils/funcutils/FunctionalFileVisitor.java index db6c43b..b0dd162 100644 --- a/base/src/main/java/bjc/utils/funcutils/FunctionalFileVisitor.java +++ b/base/src/main/java/bjc/utils/funcutils/FunctionalFileVisitor.java @@ -7,13 +7,26 @@ import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.function.BiPredicate; -/* +/** * Functional implementation of a file visitor. + * + * @author Ben Culkin */ final class FunctionalFileVisitor extends SimpleFileVisitor { + /* Our predicate to pick files. */ private final BiPredicate predicate; + /* Our action to aply to files. */ private final BiPredicate action; + /** + * Create a new file visitor, powered by functions. + * + * @param predicate + * The predicate to use to pick which files to traverse. + * + * @param action + * The function to execute on every file. + */ public FunctionalFileVisitor(final BiPredicate predicate, final BiPredicate action) { this.predicate = predicate; diff --git a/base/src/main/java/bjc/utils/funcutils/GroupPartIteration.java b/base/src/main/java/bjc/utils/funcutils/GroupPartIteration.java index f3b2254..9e4b43a 100644 --- a/base/src/main/java/bjc/utils/funcutils/GroupPartIteration.java +++ b/base/src/main/java/bjc/utils/funcutils/GroupPartIteration.java @@ -7,24 +7,46 @@ import bjc.utils.funcdata.FunctionalList; import bjc.utils.funcdata.IList; /** - * Implements a single group partitioning pass on a list + * Implements a single group partitioning pass on a list. * * @author ben * * @param - * The type of element in the list being partitioned + * The type of element in the list being partitioned */ final class GroupPartIteration implements Consumer { + /* The list we're returning. */ private final IList> returnedList; - public IList currentPartition; - private final IList rejectedItems; + /* The current partition of the list. */ + public IList currentPartition; + /* The items rejected from the current partition. */ + private final IList rejectedItems; - private int numberInCurrentPartition; - private final int numberPerPartition; + /* The number of items in the current partition. */ + private int numberInCurrentPartition; + /* The number of items in each partition. */ + private final int numberPerPartition; + /* The function to use to count an item. */ private final Function elementCounter; + /** + * Create a new group partitioning iteration. + * + * @param returned + * The list containing all of the existing partitions. + * + * @param rejects + * The items that have been rejected from a partition for being too + * large. + * + * @param nPerPart + * The combined value of items that should go into each partition. + * + * @param eleCount + * The function to use to determine the value of an item. + */ public GroupPartIteration(final IList> returned, final IList rejects, final int nPerPart, final Function eleCount) { this.returnedList = returned; @@ -48,8 +70,8 @@ final class GroupPartIteration implements Consumer { } else { final int currentElementCount = elementCounter.apply(value); - final boolean shouldReject = numberInCurrentPartition - + currentElementCount >= numberPerPartition; + final boolean shouldReject = + (numberInCurrentPartition + currentElementCount) >= numberPerPartition; if (shouldReject) { rejectedItems.add(value); diff --git a/base/src/main/java/bjc/utils/funcutils/IBuilder.java b/base/src/main/java/bjc/utils/funcutils/IBuilder.java index a96a4d6..6cbb838 100644 --- a/base/src/main/java/bjc/utils/funcutils/IBuilder.java +++ b/base/src/main/java/bjc/utils/funcutils/IBuilder.java @@ -1,29 +1,31 @@ package bjc.utils.funcutils; /** - * Generic interface for objects that implement the builder pattern + * Generic interface for objects that implement the builder pattern. * * @author ben * * @param - * The type of object being built + * The type of object being built. */ public interface IBuilder { /** - * Build the object this builder is building + * Build the object this builder is building. + * + * @return + * The built object. * - * @return The built object * @throws IllegalStateException - * if the data in the builder cannot be built into its - * corresponding object at this point in time + * If the data in the builder cannot be built into its + * corresponding object at this point in time. */ public E build(); /** - * Reset the state of this builder to its initial state + * Reset the state of this builder to its initial state. * * @throws UnsupportedOperationException - * if the builder doesn't support resetting its state + * If the builder doesn't support resetting its state. */ public default void reset() { throw new UnsupportedOperationException("Builder doesn't support state resetting"); diff --git a/base/src/main/java/bjc/utils/funcutils/Isomorphism.java b/base/src/main/java/bjc/utils/funcutils/Isomorphism.java index 2d3655e..d86ee9f 100644 --- a/base/src/main/java/bjc/utils/funcutils/Isomorphism.java +++ b/base/src/main/java/bjc/utils/funcutils/Isomorphism.java @@ -8,26 +8,25 @@ import java.util.function.Function; * @author bjculkin * * @param - * The source type of the isomorphism. + * The source type of the isomorphism. * * @param - * The destination type of isomorphism. - * + * The destination type of isomorphism. */ public class Isomorphism { + /* The function to the destination type. */ private Function toFunc; + /* The function to the source type. */ private Function fromFunc; /** * Create a new isomorphism. * * @param to - * The 'forward' function, from the source to the - * definition. + * The 'forward' function, from the source to the definition. * * @param from - * The 'backward' function, from the definition to the - * source. + * The 'backward' function, from the definition to the source. */ public Isomorphism(Function to, Function from) { toFunc = to; @@ -38,9 +37,10 @@ public class Isomorphism { * Apply the isomorphism forward. * * @param val - * The source value. + * The source value. * - * @return The destination value. + * @return + * The destination value. */ public D to(S val) { return toFunc.apply(val); @@ -50,9 +50,10 @@ public class Isomorphism { * Apply the isomorphism backward. * * @param val - * The destination value. + * The destination value. * - * @return The source value. + * @return + * The source value. */ public S from(D val) { return fromFunc.apply(val); diff --git a/base/src/main/java/bjc/utils/funcutils/LambdaLock.java b/base/src/main/java/bjc/utils/funcutils/LambdaLock.java index 62c5d32..2506d53 100644 --- a/base/src/main/java/bjc/utils/funcutils/LambdaLock.java +++ b/base/src/main/java/bjc/utils/funcutils/LambdaLock.java @@ -10,15 +10,14 @@ import java.util.function.Supplier; * properly. * * @author EVE - * */ public class LambdaLock { - private final Lock readLock; - private final Lock writeLock; + /* The read lock. */ + private final Lock readLock; + /* The write lock. */ + private final Lock writeLock; - /** - * Create a new lambda-enabled lock around a new lock. - */ + /** Create a new lambda-enabled lock around a new lock. */ public LambdaLock() { this(new ReentrantReadWriteLock()); } @@ -27,7 +26,7 @@ public class LambdaLock { * Create a new lambda-enabled lock. * * @param lck - * The lock to wrap. + * The lock to wrap. */ public LambdaLock(final ReadWriteLock lck) { readLock = lck.readLock(); @@ -38,9 +37,10 @@ public class LambdaLock { * Execute an action with the read lock taken. * * @param supp - * The action to call. + * The action to call. * - * @return The result of the action. + * @return + * The result of the action. */ public T read(final Supplier supp) { readLock.lock(); @@ -56,9 +56,10 @@ public class LambdaLock { * Execute an action with the write lock taken. * * @param supp - * The action to call. + * The action to call. * - * @return The result of the action. + * @return + * The result of the action. */ public T write(final Supplier supp) { writeLock.lock(); @@ -74,8 +75,7 @@ public class LambdaLock { * Execute an action with the read lock taken. * * @param action - * The action to call. - * + * The action to call. */ public void read(final Runnable action) { readLock.lock(); @@ -91,7 +91,7 @@ public class LambdaLock { * Execute an action with the write lock taken. * * @param action - * The action to call. + * The action to call. */ public void write(final Runnable action) { writeLock.lock(); @@ -102,4 +102,4 @@ public class LambdaLock { writeLock.unlock(); } } -} \ No newline at end of file +} diff --git a/base/src/main/java/bjc/utils/funcutils/ListUtils.java b/base/src/main/java/bjc/utils/funcutils/ListUtils.java index c0daa1e..2441a80 100644 --- a/base/src/main/java/bjc/utils/funcutils/ListUtils.java +++ b/base/src/main/java/bjc/utils/funcutils/ListUtils.java @@ -10,21 +10,23 @@ import bjc.utils.funcdata.IList; /** * Utilities for manipulating FunctionalLists that don't belong in the class - * itself + * itself. * * @author ben - * */ public class ListUtils { + /* The max amount of times to try to partition things. */ private static final int MAX_NTRIESPART = 50; /** * Collapse a string of tokens into a single string without adding any - * spaces + * spaces. * * @param input - * The list of tokens to collapse - * @return The collapsed string of tokens + * The list of tokens to collapse. + * + * @return + * The collapsed string of tokens. */ public static String collapseTokens(final IList input) { if (input == null) throw new NullPointerException("Input must not be null"); @@ -34,24 +36,29 @@ public class ListUtils { /** * Collapse a string of tokens into a single string, adding the desired - * separator after each token + * separator after each token. * * @param input - * The list of tokens to collapse + * The list of tokens to collapse. + * * @param seperator - * The separator to use for separating tokens - * @return The collapsed string of tokens + * The separator to use for separating tokens. + * + * @return + * The collapsed string of tokens. */ public static String collapseTokens(final IList input, final String seperator) { - if (input == null) + if (input == null) { throw new NullPointerException("Input must not be null"); - else if (seperator == null) throw new NullPointerException("Seperator must not be null"); + } else if (seperator == null) { + throw new NullPointerException("Seperator must not be null"); + } - if (input.getSize() < 1) + if (input.getSize() < 1) { return ""; - else if (input.getSize() == 1) + } else if (input.getSize() == 1) { return input.first(); - else { + } else { final StringBuilder state = new StringBuilder(); int i = 1; @@ -70,21 +77,25 @@ public class ListUtils { } /** - * Select a number of random items from the list without replacement + * Select a number of random items from the list without replacement. * * @param - * The type of items to select + * The type of items to select. + * * @param list - * The list to select from + * The list to select from. + * * @param number - * The number of items to selet + * The number of items to selet. + * * @param rng - * A function that creates a random number from 0 to the - * desired number - * @return A new list containing the desired number of items randomly - * selected from the specified list without replacement + * A function that creates a random number from 0 to the + * desired number. + * + * @return + * A new list containing the desired number of items randomly + * selected from the specified list without replacement. */ - public static IList drawWithoutReplacement(final IList list, final int number, final Function rng) { final IList selected = new FunctionalList<>(new ArrayList<>(number)); @@ -95,19 +106,13 @@ public class ListUtils { E element = null; for (final int index = 0; itr.hasNext(); element = itr.next()) { - /* - * n - m - */ + /* n - m */ final int winningChance = number - selected.getSize(); - /* - * N - t - */ + /* N - t */ final int totalChance = total - (index - 1); - /* - * Probability of selecting the t+1'th element - */ + /* Probability of selecting the t+1'th element */ if (NumberUtils.isProbable(winningChance, totalChance, rng)) { selected.add(element); } @@ -117,19 +122,24 @@ public class ListUtils { } /** - * Select a number of random items from the list, with replacement + * Select a number of random items from the list, with replacement. * * @param - * The type of items to select + * The type of items to select. + * * @param list - * The list to select from + * The list to select from. + * * @param number - * The number of items to selet + * The number of items to select. + * * @param rng - * A function that creates a random number from 0 to the - * desired number - * @return A new list containing the desired number of items randomly - * selected from the specified list + * A function that creates a random number from 0 to the + * desired number. + * + * @return + * A new list containing the desired number of items randomly + * selected from the specified list. */ public static IList drawWithReplacement(final IList list, final int number, final Function rng) { @@ -144,57 +154,51 @@ public class ListUtils { /** * Partition a list into a list of lists, where each element can count - * for more than one element in a partition + * for more than one element in a partition. * * @param - * The type of elements in the list to partition + * The type of elements in the list to partition. * * @param input - * The list to partition + * The list to partition. + * * @param counter - * The function to determine the count for each element - * for + * The function to determine the count for each element for. + * * @param partitionSize - * The number of elements to put in each partition + * The number of elements to put in each partition. * - * @return A list partitioned according to the above rules + * @return + * A list partitioned according to the above rules. */ public static IList> groupPartition(final IList input, final Function counter, final int partitionSize) { - if (input == null) + if (input == null) { throw new NullPointerException("Input list must not be null"); - else if (counter == null) + } else if (counter == null) { throw new NullPointerException("Counter must not be null"); - else if (partitionSize < 1 || partitionSize > input.getSize()) { + } else if (partitionSize < 1 || partitionSize > input.getSize()) { final String fmt = "%d is not a valid partition size. Must be between 1 and %d"; final String msg = String.format(fmt, partitionSize, input.getSize()); throw new IllegalArgumentException(msg); } - /* - * List that holds our results - */ + /* List that holds our results. */ final IList> returned = new FunctionalList<>(); - /* - * List that holds elements rejected during current pass - */ + /* List that holds elements rejected during current pass. */ final IList rejected = new FunctionalList<>(); final GroupPartIteration it = new GroupPartIteration<>(returned, rejected, partitionSize, counter); - /* - * Run up to a certain number of passes - */ + /* Run up to a certain number of passes. */ for (int numberOfIterations = 0; numberOfIterations < MAX_NTRIESPART && !rejected.isEmpty(); numberOfIterations++) { input.forEach(it); if (rejected.isEmpty()) { - /* - * Nothing was rejected, so we're done - */ + /* Nothing was rejected, so we're done. */ return returned; } } @@ -208,13 +212,16 @@ public class ListUtils { } /** - * Merge the contents of a bunch of lists together into a single list + * Merge the contents of a bunch of lists together into a single list. * * @param - * The type of value in this lists + * The type of value in this lists. + * * @param lists - * The values in the lists to merge - * @return A list containing all the elements of the lists + * The values in the lists to merge. + * + * @return + * A list containing all the elements of the lists. */ @SafeVarargs public static IList mergeLists(final IList... lists) { @@ -230,21 +237,28 @@ public class ListUtils { } /** - * Pad the provided list out to the desired size + * Pad the provided list out to the desired size. * * @param - * The type of elements in the list + * The type of elements in the list. + * * @param list - * The list to pad out + * The list to pad out. + * * @param counter - * The function to count elements with + * The function to count elements with. + * * @param size - * The desired size of the list + * The desired size of the list. + * * @param padder - * The function to get elements to pad with - * @return The list, padded to the desired size + * The function to get elements to pad with. + * + * @return + * The list, padded to the desired size. + * * @throws IllegalArgumentException - * if the list couldn't be padded to the desired size + * If the list couldn't be padded to the desired size. */ public static IList padList(final IList list, final Function counter, final int size, final Supplier padder) { @@ -259,9 +273,7 @@ public class ListUtils { } if (count % size != 0) { - /* - * We need to pad - */ + /* We need to pad */ int needed = count % size; int threshold = 0; diff --git a/base/src/main/java/bjc/utils/funcutils/NumberUtils.java b/base/src/main/java/bjc/utils/funcutils/NumberUtils.java index 770d3a5..c3d52fa 100644 --- a/base/src/main/java/bjc/utils/funcutils/NumberUtils.java +++ b/base/src/main/java/bjc/utils/funcutils/NumberUtils.java @@ -3,27 +3,29 @@ package bjc.utils.funcutils; import java.util.function.Function; /** - * Utility functions for dealing with numbers + * Utility functions for dealing with numbers. * * @author ben - * */ public class NumberUtils { /** - * Compute the falling factorial of a number + * Compute the falling factorial of a number. * * @param value - * The number to compute + * The number to compute. + * * @param power - * The power to do the falling factorial for - * @return The falling factorial of the number to the power + * The power to do the falling factorial for. + * + * @return + * The falling factorial of the number to the power. */ public static int fallingFactorial(final int value, final int power) { - if (power == 0) + if (power == 0) { return 1; - else if (power == 1) + } else if (power == 1) { return value; - else { + } else { int result = 1; for (int currentSub = 0; currentSub < power + 1; currentSub++) { @@ -35,15 +37,18 @@ public class NumberUtils { } /** - * Evaluates a linear probability distribution + * Evaluates a linear probability distribution. * * @param winning - * The number of winning possibilities + * The number of winning possibilities. + * * @param total - * The number of total possibilities + * The number of total possibilities. + * * @param rng - * The function to use to generate a random possibility - * @return Whether or not a random possibility was a winning one + * The function to use to generate a random possibility. + * + * @return Whether or not a random possibility was a winning one. */ public static boolean isProbable(final int winning, final int total, final Function rng) { return rng.apply(total) < winning; @@ -53,15 +58,16 @@ public class NumberUtils { * Check if a number is in an inclusive range. * * @param min - * The minimum value of the range. + * The minimum value of the range. * * @param max - * The maximum value of the range. + * The maximum value of the range. * * @param i - * The number to check. + * The number to check. * - * @return Whether the number is in the range. + * @return + * Whether the number is in the range. */ public static boolean between(final int min, final int max, final int i) { return i >= min && i <= max; diff --git a/base/src/main/java/bjc/utils/funcutils/StringUtils.java b/base/src/main/java/bjc/utils/funcutils/StringUtils.java index 62f78f5..ba4ebca 100644 --- a/base/src/main/java/bjc/utils/funcutils/StringUtils.java +++ b/base/src/main/java/bjc/utils/funcutils/StringUtils.java @@ -7,23 +7,24 @@ import java.util.regex.Pattern; import com.ibm.icu.text.BreakIterator; /** - * Utility methods for operations on strings + * Utility methods for operations on strings. * * @author ben - * */ public class StringUtils { /** * Check if a string consists only of one or more matches of a regular - * expression + * expression. * * @param input - * The string to check + * The string to check. + * * @param rRegex - * The regex to see if the string only contains matches - * of - * @return Whether or not the string consists only of multiple matches - * of the provided regex + * The regex to see if the string only contains matches of. + * + * @return + * Whether or not the string consists only of multiple matches of + * the provided regex. */ public static boolean containsOnly(final String input, final String rRegex) { if (input == null) @@ -36,18 +37,19 @@ public class StringUtils { * First, we match the beginning of the string. Then, we start a * non-capturing group whose contents are the passed in regex. * That group is then matched one or more times and the pattern - * matches to the end of the string + * matches to the end of the string. */ return input.matches("\\A(?:" + rRegex + ")+\\Z"); } /** - * Indent the string being built in a StringBuilder n levels + * Indent the string being built in a StringBuilder n levels. * * @param builder - * The builder to indent in + * The builder to indent in. + * * @param levels - * The number of levels to indent + * The number of levels to indent. */ public static void indentNLevels(final StringBuilder builder, final int levels) { for (int i = 0; i < levels; i++) { @@ -57,14 +59,17 @@ public class StringUtils { /** * Print out a deque with a special case for easily showing a deque is - * empty + * empty. * * @param - * The type in the deque + * The type in the deque. + * * @param queue - * The deque to print - * @return A string version of the deque, with allowance for an empty - * deque + * The deque to print. + * + * @return + * A string version of the deque, with allowance for an empty + * deque. */ public static String printDeque(final Deque queue) { return queue.isEmpty() ? "(none)" : queue.toString(); @@ -74,14 +79,16 @@ public class StringUtils { * Converts a sequence to an English list. * * @param objects - * The sequence to convert to an English list. + * The sequence to convert to an English list. + * * @param join - * The string to use for separating the last element from - * the rest. + * The string to use for separating the last element from the rest. + * * @param comma - * The string to use as a comma + * The string to use as a comma * - * @return The sequence as an English list. + * @return + * The sequence as an English list. */ public static String toEnglishList(final Object[] objects, final String join, final String comma) { if (objects == null) throw new NullPointerException("Sequence must not be null"); @@ -93,32 +100,25 @@ public class StringUtils { switch (objects.length) { case 0: - /* - * Empty list. - */ + /* Empty list. */ break; case 1: - /* - * One item. - */ + /* One item. */ sb.append(objects[0].toString()); break; case 2: - /* - * Two items. - */ + /* Two items. */ sb.append(objects[0].toString()); sb.append(" " + joiner + " "); sb.append(objects[1].toString()); break; default: - /* - * Three or more items. - */ + /* Three or more items. */ for (int i = 0; i < objects.length - 1; i++) { sb.append(objects[i].toString()); sb.append(coma + " "); } + /* * Uncomment this to remove serial commas. * @@ -137,12 +137,13 @@ public class StringUtils { * Converts a sequence to an English list. * * @param objects - * The sequence to convert to an English list. + * The sequence to convert to an English list. + * * @param join - * The string to use for separating the last element from - * the rest. + * The string to use for separating the last element from the rest. * - * @return The sequence as an English list. + * @return + * The sequence as an English list. */ public static String toEnglishList(final Object[] objects, final String join) { return toEnglishList(objects, join, ","); @@ -152,25 +153,30 @@ public class StringUtils { * Converts a sequence to an English list. * * @param objects - * The sequence to convert to an English list. + * The sequence to convert to an English list. + * * @param and - * Whether to use 'and' or 'or'. + * Whether to use 'and' or 'or'. * - * @return The sequence as an English list. + * @return + * The sequence as an English list. */ public static String toEnglishList(final Object[] objects, final boolean and) { - if (and) + if (and) { return toEnglishList(objects, "and"); - else return toEnglishList(objects, "or"); + } else { + return toEnglishList(objects, "or"); + } } /** * Count the number of graphemes in a string. * * @param value - * The string to check. + * The string to check. * - * @return The number of graphemes in the string. + * @return + * The number of graphemes in the string. */ public static int graphemeCount(final String value) { final BreakIterator it = BreakIterator.getCharacterInstance(); @@ -184,6 +190,15 @@ public class StringUtils { return count; } + /** + * Count the number of times a pattern matches in a given string. + * + * @param value + * The string to count occurances in. + * + * @param pattern + * The pattern to count occurances of. + */ public static int countMatches(final String value, final String pattern) { Matcher mat = Pattern.compile(pattern).matcher(value); diff --git a/base/src/main/java/bjc/utils/funcutils/TreeUtils.java b/base/src/main/java/bjc/utils/funcutils/TreeUtils.java index dcd5738..3308fb8 100644 --- a/base/src/main/java/bjc/utils/funcutils/TreeUtils.java +++ b/base/src/main/java/bjc/utils/funcutils/TreeUtils.java @@ -28,11 +28,10 @@ public class TreeUtils { return paths; } + /* Find a path in a tree. */ private static void findPath(ITree subtree, LinkedList path, Predicate leafMarker, IList> paths) { if(subtree.getChildrenCount() == 0 && leafMarker.test(subtree.getHead())) { - /* - * We're at a matching leaf node. Add it. - */ + /* We're at a matching leaf node. Add it. */ IList finalPath = new FunctionalList<>(); for(T ePath : path) { @@ -43,9 +42,7 @@ public class TreeUtils { paths.add(finalPath); } else { - /* - * Check the children of this node. - */ + /* Check the children of this node. */ path.add(subtree.getHead()); subtree.doForChildren((child) -> findPath(child, path, leafMarker, paths)); diff --git a/base/src/main/java/bjc/utils/funcutils/TriConsumer.java b/base/src/main/java/bjc/utils/funcutils/TriConsumer.java index f30386c..a41cde0 100644 --- a/base/src/main/java/bjc/utils/funcutils/TriConsumer.java +++ b/base/src/main/java/bjc/utils/funcutils/TriConsumer.java @@ -6,12 +6,13 @@ package bjc.utils.funcutils; * @author EVE * * @param - * Type of the first argument. + * Type of the first argument. + * * @param - * Type of the second argument. - * @param - * Type of the third argument. + * Type of the second argument. * + * @param + * Type of the third argument. */ @FunctionalInterface public interface TriConsumer { @@ -19,13 +20,13 @@ public interface TriConsumer { * Perform the action. * * @param a - * The first parameter. + * The first parameter. * * @param b - * The second parameter. + * The second parameter. * * @param c - * The third parameter. + * The third parameter. */ public void accept(A a, B b, C c); } diff --git a/base/src/main/java/bjc/utils/gen/RandomGrammar.java b/base/src/main/java/bjc/utils/gen/RandomGrammar.java index 3de08d6..978accb 100644 --- a/base/src/main/java/bjc/utils/gen/RandomGrammar.java +++ b/base/src/main/java/bjc/utils/gen/RandomGrammar.java @@ -9,12 +9,10 @@ import bjc.utils.funcdata.IList; * @author ben * * @param - * The type of grammar elements to use. + * The type of grammar elements to use. */ public class RandomGrammar extends WeightedGrammar { - /** - * Create a new random grammar. - */ + /** Create a new random grammar. */ public RandomGrammar() { rules = new FunctionalMap<>(); } @@ -23,9 +21,10 @@ public class RandomGrammar extends WeightedGrammar { * Add cases to a specified rule. * * @param rule - * The name of the rule to add cases to. + * The name of the rule to add cases to. + * * @param cases - * The cases to add for this rule. + * The cases to add for this rule. */ @SafeVarargs public final void addCases(final E rule, final IList... cases) { @@ -38,9 +37,10 @@ public class RandomGrammar extends WeightedGrammar { * Create a rule with the specified name and cases. * * @param rule - * The name of the rule to add. + * The name of the rule to add. + * * @param cases - * The cases to add for this rule. + * The cases to add for this rule. */ @SafeVarargs public final void makeRule(final E rule, final IList... cases) { @@ -55,9 +55,10 @@ public class RandomGrammar extends WeightedGrammar { * Create a rule with the specified name and cases. * * @param rule - * The name of the rule to add. + * The name of the rule to add. + * * @param cases - * The cases to add for this rule. + * The cases to add for this rule. */ public void makeRule(final E rule, final IList> cases) { if (cases == null) throw new NullPointerException("Cases must not be null"); diff --git a/base/src/main/java/bjc/utils/gen/WeightedGrammar.java b/base/src/main/java/bjc/utils/gen/WeightedGrammar.java index 7777ad8..1fbba02 100644 --- a/base/src/main/java/bjc/utils/gen/WeightedGrammar.java +++ b/base/src/main/java/bjc/utils/gen/WeightedGrammar.java @@ -19,48 +19,31 @@ import bjc.utils.funcdata.IMap; * @author ben * * @param - * The values that make up sentences of this grammar. + * The values that make up sentences of this grammar. */ public class WeightedGrammar { - /** - * The initial rule of the grammar - */ + /** The initial rule of the grammar */ protected String initialRule; - /** - * The rules currently in this grammar - */ + /** The rules currently in this grammar */ protected IMap>> rules; - /** - * The random number generator used for random numbers - */ + /** The random number generator used for random numbers */ private Random rng; - /** - * All of the subgrammars of this grammar - */ + /** All of the subgrammars of this grammar */ protected IMap> subgrammars; - /** - * Rules that require special handling - */ + /** Rules that require special handling */ private IMap>> specialRules; - /** - * Predicate for marking special tokens - */ - + /** Predicate for marking special tokens */ private Predicate specialMarker; - /** - * Action for special tokens - */ + /** Action for special tokens */ private BiFunction, IList> specialAction; - /** - * Create a new weighted grammar. - */ + /** Create a new weighted grammar. */ public WeightedGrammar() { rules = new FunctionalMap<>(); subgrammars = new FunctionalMap<>(); @@ -72,7 +55,7 @@ public class WeightedGrammar { * randomness. * * @param source - * The source of randomness to use + * The source of randomness to use */ public WeightedGrammar(final Random source) { this(); @@ -86,10 +69,10 @@ public class WeightedGrammar { * Configure the action to perform on special tokens. * * @param marker - * The marker to find special tokens. + * The marker to find special tokens. * * @param action - * The action to take on those tokens. + * The action to take on those tokens. */ public void configureSpecial(final Predicate marker, final BiFunction, IList> action) { @@ -101,15 +84,17 @@ public class WeightedGrammar { * Adds a special rule to the grammar. * * @param ruleName - * The name of the special rule. + * The name of the special rule. * * @param cse - * The case for the rule. + * The case for the rule. */ public void addSpecialRule(final E ruleName, final Supplier> cse) { - if (ruleName == null) + if (ruleName == null) { throw new NullPointerException("Rule name must not be null"); - else if (cse == null) throw new NullPointerException("Case must not be null"); + } else if (cse == null) { + throw new NullPointerException("Case must not be null"); + } specialRules.put(ruleName, cse); } @@ -118,33 +103,42 @@ public class WeightedGrammar { * Add a case to an already existing rule. * * @param ruleName - * The rule to add a case to. + * The rule to add a case to. + * * @param probability - * The probability for this rule to be chosen. + * The probability for this rule to be chosen. + * * @param cse - * The case being added. + * The case being added. */ public void addCase(final E ruleName, final int probability, final IList cse) { - if (ruleName == null) + if (ruleName == null) { throw new NullPointerException("Rule name must be not null"); - else if (cse == null) throw new NullPointerException("Case body must not be null"); + } else if (cse == null) { + throw new NullPointerException("Case body must not be null"); + } rules.get(ruleName).addProbability(probability, cse); } /** - * Add a alias for an existing subgrammar + * Add a alias for an existing subgrammar. * * @param name - * The name of the subgrammar to alias + * The name of the subgrammar to alias. + * * @param alias - * The alias of the subgrammar - * @return Whether the alias was succesfully created + * The alias of the subgrammar. + * + * @return + * Whether the alias was succesfully created. */ public boolean addGrammarAlias(final E name, final E alias) { - if (name == null) + if (name == null) { throw new NullPointerException("Subgrammar name must not be null"); - else if (alias == null) throw new NullPointerException("Subgrammar alias must not be null"); + } else if (alias == null) { + throw new NullPointerException("Subgrammar alias must not be null"); + } if (subgrammars.containsKey(alias)) return false; @@ -160,8 +154,10 @@ public class WeightedGrammar { * Add a new rule with no cases. * * @param name - * The name of the rule to add. - * @return Whether or not the rule was successfully added. + * The name of the rule to add. + * + * @return + * Whether or not the rule was successfully added. */ public boolean addRule(final E name) { if (rng == null) { @@ -177,15 +173,20 @@ public class WeightedGrammar { * Add a new rule with a set of cases. * * @param name - * The name of the rule to add. + * The name of the rule to add. + * * @param cases - * The set of cases for the rule. - * @return Whether or not the rule was succesfully added. + * The set of cases for the rule. + * + * @return + * Whether or not the rule was succesfully added. */ public boolean addRule(final E name, final WeightedRandom> cases) { - if (name == null) + if (name == null) { throw new NullPointerException("Name must not be null"); - else if (cases == null) throw new NullPointerException("Cases must not be null"); + } else if (cases == null) { + throw new NullPointerException("Cases must not be null"); + } if (rules.containsKey(name)) return false; @@ -197,15 +198,20 @@ public class WeightedGrammar { * Add a subgrammar. * * @param name - * The name of the subgrammar. + * The name of the subgrammar. + * * @param subgrammar - * The subgrammar to add. - * @return Whether or not the subgrammar was succesfully added. + * The subgrammar to add. + * + * @return + * Whether or not the subgrammar was succesfully added. */ public boolean addSubgrammar(final E name, final WeightedGrammar subgrammar) { - if (name == null) + if (name == null) { throw new NullPointerException("Subgrammar name must not be null"); - else if (subgrammar == null) throw new NullPointerException("Subgrammar must not be null"); + } else if (subgrammar == null) { + throw new NullPointerException("Subgrammar must not be null"); + } if (subgrammars.containsKey(name)) return false; @@ -217,7 +223,7 @@ public class WeightedGrammar { * Remove a rule with the specified name. * * @param name - * The name of the rule to remove. + * The name of the rule to remove. */ public void deleteRule(final E name) { if (name == null) throw new NullPointerException("Rule name must not be null"); @@ -229,7 +235,7 @@ public class WeightedGrammar { * Remove a subgrammar with the specified name. * * @param name - * The name of the subgrammar to remove. + * The name of the subgrammar to remove. */ public void deleteSubgrammar(final E name) { if (name == null) throw new NullPointerException("Rule name must not be null"); @@ -243,8 +249,10 @@ public class WeightedGrammar { * Only generates sentences one layer deep. * * @param ruleName - * The rule to test. - * @return A set of sentences generated by the specified rule. + * The rule to test. + * + * @return + * A set of sentences generated by the specified rule. */ public IList> generateDebugValues(final E ruleName) { if (ruleName == null) throw new NullPointerException("Rule name must not be null"); @@ -264,28 +272,29 @@ public class WeightedGrammar { * Generate a generic sentence from a initial rule. * * @param - * The type of the transformed output + * The type of the transformed output * * @param initRules - * The initial rule to start with. + * The initial rule to start with. * * @param tokenTransformer - * The function to transform grammar output into - * something. + * The function to transform grammar output into something. * * @param spacer - * The spacer element to add in between output tokens. + * The spacer element to add in between output tokens. * - * @return A randomly generated sentence from the specified initial - * rule. + * @return + * A randomly generated sentence from the specified initial rule. */ public IList generateGenericValues(final E initRules, final Function tokenTransformer, final T spacer) { - if (initRules == null) + if (initRules == null) { throw new NullPointerException("Initial rule must not be null"); - else if (tokenTransformer == null) + } else if (tokenTransformer == null) { throw new NullPointerException("Transformer must not be null"); - else if (spacer == null) throw new NullPointerException("Spacer must not be null"); + } else if (spacer == null) { + throw new NullPointerException("Spacer must not be null"); + } final IList returnedList = new FunctionalList<>(); @@ -297,6 +306,10 @@ public class WeightedGrammar { } } + /* + * @NOTE + * Can this loop be simplified in some way? + */ for (final E initRule : genRules.toIterable()) { if (specialRules.containsKey(initRule)) { for (final E rulePart : specialRules.get(initRule).get().toIterable()) { @@ -346,11 +359,14 @@ public class WeightedGrammar { * Generate a random list of grammar elements from a given initial rule. * * @param initRule - * The initial rule to start with. + * The initial rule to start with. + * * @param spacer - * The item to use to space the list. - * @return A list of random grammar elements generated by the specified - * rule. + * The item to use to space the list. + * + * @return + * A list of random grammar elements generated by the specified + * rule. */ public IList generateListValues(final E initRule, final E spacer) { final IList retList = generateGenericValues(initRule, strang -> strang, spacer); @@ -359,27 +375,30 @@ public class WeightedGrammar { } /** - * Get the initial rule of this grammar + * Get the initial rule of this grammar. * - * @return The initial rule of this grammar + * @return + * The initial rule of this grammar. */ public String getInitialRule() { return initialRule; } /** - * Returns the number of rules in this grammar + * Returns the number of rules in this grammar. * - * @return The number of rules in this grammar + * @return + * The number of rules in this grammar. */ public int getRuleCount() { return rules.size(); } /** - * Returns a set containing all of the rules in this grammar + * Returns a set containing all of the rules in this grammar. * - * @return The set of all rule names in this grammar + * @return + * The set of all rule names in this grammar. */ public IList getRuleNames() { final IList ruleNames = new FunctionalList<>(); @@ -394,8 +413,10 @@ public class WeightedGrammar { * Get the subgrammar with the specified name. * * @param name - * The name of the subgrammar to get. - * @return The subgrammar with the specified name. + * The name of the subgrammar to get. + * + * @return + * The subgrammar with the specified name. */ public WeightedGrammar getSubgrammar(final E name) { if (name == null) throw new NullPointerException("Subgrammar name must not be null"); @@ -406,7 +427,8 @@ public class WeightedGrammar { /** * Check if this grammar has an initial rule * - * @return Whether or not this grammar has an initial rule + * @return + * Whether or not this grammar has an initial rule */ public boolean hasInitialRule() { return initialRule != null && !initialRule.equalsIgnoreCase(""); @@ -416,25 +438,29 @@ public class WeightedGrammar { * Check if this grammar has a given rule. * * @param ruleName - * The rule to check for. + * The rule to check for. * - * @return Whether or not the grammar has a rule by that name. + * @return + * Whether or not the grammar has a rule by that name. */ public boolean hasRule(final E ruleName) { return rules.containsKey(ruleName) || specialRules.containsKey(ruleName); } /** - * Prefix a given rule with a token multiple times + * Prefix a given rule with a token multiple times. * * @param ruleName - * The name of the rule to prefix + * The name of the rule to prefix. + * * @param prefixToken - * The token to prefix to the rules + * The token to prefix to the rules. + * * @param additionalProbability - * The additional probability of the tokens + * The additional probability of the tokens. + * * @param numberOfTimes - * The number of times to prefix the token + * The number of times to prefix the token. */ public void multiPrefixRule(final E ruleName, final E prefixToken, final int additionalProbability, final int numberOfTimes) { @@ -449,6 +475,10 @@ public class WeightedGrammar { final IList>> newResults = new FunctionalList<>(); + /* + * @NOTE + * Can this be simplified? + */ rule.getValues().forEach((pair) -> { final IList> newRule = new FunctionalList<>(); @@ -486,19 +516,24 @@ public class WeightedGrammar { /** * Create a series of alternatives for a rule by prefixing them with a - * given token + * given token. * * @param additionalProbability - * The amount to adjust the probability by + * The amount to adjust the probability by. + * * @param ruleName - * The name of the rule to prefix + * The name of the rule to prefix. + * * @param prefixToken - * The token to prefix to the rule + * The token to prefix to the rule. */ public void prefixRule(final E ruleName, final E prefixToken, final int additionalProbability) { - if (ruleName == null) + if (ruleName == null) { throw new NullPointerException("Rule name must not be null"); - else if (prefixToken == null) throw new NullPointerException("Prefix token must not be null"); + } + else if (prefixToken == null) { + throw new NullPointerException("Prefix token must not be null"); + } final WeightedRandom> rule = rules.get(ruleName); @@ -524,29 +559,33 @@ public class WeightedGrammar { } /** - * Set the initial rule of the graphic + * Set the initial rule of the grammar. * * @param initRule - * The initial rule of this grammar + * The initial rule of this grammar. */ public void setInitialRule(final String initRule) { this.initialRule = initRule; } /** - * Suffix a token to a rule + * Suffix a token to a rule. * * @param ruleName - * The rule to suffix + * The rule to suffix. + * * @param suffixToken - * The token to prefix to the rule + * The token to prefix to the rule. + * * @param additionalProbability - * Additional probability of the prefixed rule + * Additional probability of the prefixed rule. */ public void suffixRule(final E ruleName, final E suffixToken, final int additionalProbability) { - if (ruleName == null) + if (ruleName == null) { throw new NullPointerException("Rule name must not be null"); - else if (suffixToken == null) throw new NullPointerException("Prefix token must not be null"); + } else if (suffixToken == null) { + throw new NullPointerException("Prefix token must not be null"); + } final WeightedRandom> rule = rules.get(ruleName); diff --git a/base/src/main/java/bjc/utils/gen/WeightedRandom.java b/base/src/main/java/bjc/utils/gen/WeightedRandom.java index 18225ef..abba36a 100644 --- a/base/src/main/java/bjc/utils/gen/WeightedRandom.java +++ b/base/src/main/java/bjc/utils/gen/WeightedRandom.java @@ -15,32 +15,25 @@ import bjc.utils.funcdata.IList; * @author ben * * @param - * The type of values that are randomly selected. + * The type of values that are randomly selected. */ public class WeightedRandom { - /* - * The list of probabilities for each result - */ + /* The list of probabilities for each result */ private final IList probabilities; - - /* - * The list of possible results to pick from - */ + /* The list of possible results to pick from */ private final IList results; - /* - * The source for any needed random numbers - */ + /* The source for any needed random numbers */ private final Random source; - + /* The total chance for all values. */ private int totalChance; /** * Create a new weighted random generator with the specified source of - * randomness + * randomness. * * @param src - * The source of randomness to use. + * The source of randomness to use. */ public WeightedRandom(final Random src) { probabilities = new FunctionalList<>(); @@ -55,9 +48,10 @@ public class WeightedRandom { * Add a probability for a specific result to be given. * * @param chance - * The chance to get this result. + * The chance to get this result. + * * @param result - * The result to get when the chance comes up. + * The result to get when the chance comes up. */ public void addProbability(final int chance, final E result) { probabilities.add(chance); @@ -69,11 +63,12 @@ public class WeightedRandom { /** * Generate a weighted random value. * - * @return A random value selected in a weighted fashion. + * @return + * A random value selected in a weighted fashion. */ public E generateValue() { - final IHolder value = new Identity<>(source.nextInt(totalChance)); - final IHolder current = new Identity<>(); + final IHolder value = new Identity<>(source.nextInt(totalChance)); + final IHolder current = new Identity<>(); final IHolder picked = new Identity<>(true); probabilities.forEachIndexed((index, probability) -> { @@ -94,7 +89,8 @@ public class WeightedRandom { /** * Return a list of values that can be generated by this generator * - * @return A list of all the values that can be generated + * @return + * A list of all the values that can be generated */ public IList getResults() { return results; @@ -104,7 +100,8 @@ public class WeightedRandom { * Return a list containing values that can be generated paired with the * probability of those values being generated * - * @return A list of pairs of values and value probabilities + * @return + * A list of pairs of values and value probabilities */ public IList> getValues() { return probabilities.pairWith(results); diff --git a/base/src/main/java/bjc/utils/graph/AdjacencyMap.java b/base/src/main/java/bjc/utils/graph/AdjacencyMap.java index 446ab5b..58ce107 100644 --- a/base/src/main/java/bjc/utils/graph/AdjacencyMap.java +++ b/base/src/main/java/bjc/utils/graph/AdjacencyMap.java @@ -20,20 +20,22 @@ import bjc.utils.funcutils.FuncUtils; * @author ben * * @param - * The type of the nodes in the graph + * The type of the nodes in the graph */ public class AdjacencyMap { /** * Create an adjacency map from a stream of text * * @param stream - * The stream of text to read in - * @return An adjacency map defined by the text + * The stream of text to read in + * + * @return + * An adjacency map defined by the text */ public static AdjacencyMap fromStream(final InputStream stream) { if (stream == null) throw new NullPointerException("Input source must not be null"); - // Create the adjacency map + /* Create the adjacency map. */ AdjacencyMap adjacency; try (Scanner input = new Scanner(stream)) { @@ -44,12 +46,14 @@ public class AdjacencyMap { final String possible = input.next(); try { - // First, read in number of vertices + /* First, read in number of vertices. */ vertexCount = Integer.parseInt(possible); } catch (final NumberFormatException nfex) { - final InputMismatchException imex = new InputMismatchException( - "The first line must contain the number of vertices. " + possible - + " is not a valid number"); + String msg = String.format( + "The first line must contain the number of vertices. %s is not a valid number", + possible); + + final InputMismatchException imex = new InputMismatchException(msg); imex.initCause(nfex); @@ -75,12 +79,16 @@ public class AdjacencyMap { return adjacency; } + /* Read a row of edges. */ private static void readRow(final AdjacencyMap adjacency, final int vertexCount, final IHolder row, final String strang) { final String[] parts = strang.split(" "); - if (parts.length != vertexCount) - throw new InputMismatchException("Must specify a weight for all " + vertexCount + " vertices"); + if (parts.length != vertexCount) { + String msg = String.format("Must specify a weight for all %d vertices", vertexCount); + + throw new InputMismatchException(msg); + } int column = 0; @@ -90,9 +98,9 @@ public class AdjacencyMap { try { weight = Integer.parseInt(part); } catch (final NumberFormatException nfex) { - final InputMismatchException imex = new InputMismatchException( - "" + part + " is not a valid weight."); + String msg = String.format("%d is not a valid weight.", part); + final InputMismatchException imex = new InputMismatchException(); imex.initCause(nfex); throw imex; @@ -106,16 +114,14 @@ public class AdjacencyMap { row.transform((rowNumber) -> rowNumber + 1); } - /** - * The backing storage of the map - */ + /** The backing storage of the map */ private final IMap> adjacency = new FunctionalMap<>(); /** * Create a new map from a set of vertices * * @param vertices - * The set of vertices to create a map from + * The set of vertices to create a map from */ public AdjacencyMap(final IList vertices) { if (vertices == null) throw new NullPointerException("Vertices must not be null"); @@ -134,7 +140,8 @@ public class AdjacencyMap { /** * Check if the graph is directed * - * @return Whether or not the graph is directed + * @return + * Whether or not the graph is directed */ public boolean isDirected() { final IHolder result = new Identity<>(true); @@ -153,32 +160,40 @@ public class AdjacencyMap { } /** - * Set the weight of an edge + * Set the weight of an edge. * * @param source - * The source node of the edge + * The source node of the edge. * @param target - * The target node of the edge + * The target node of the edge. * @param weight - * The weight of the edge + * The weight of the edge. */ public void setWeight(final T source, final T target, final int weight) { - if (source == null) + if (source == null) { throw new NullPointerException("Source vertex must not be null"); - else if (target == null) throw new NullPointerException("Target vertex must not be null"); + } else if (target == null) { + throw new NullPointerException("Target vertex must not be null"); + } + + if (!adjacency.containsKey(source)) { + String msg = String.format("Source vertex %s isn't present in map", source); - if (!adjacency.containsKey(source)) - throw new IllegalArgumentException("Source vertex " + source + " isn't present in map"); - else if (!adjacency.containsKey(target)) - throw new IllegalArgumentException("Target vertex " + target + " isn't present in map"); + throw new IllegalArgumentException(msg); + } else if (!adjacency.containsKey(target)) { + String msg = String.format("Target vertex %s isn't present in map", target); + + throw new IllegalArgumentException(msg); + } adjacency.get(source).put(target, weight); } /** - * Convert this to a different graph representation + * Convert this to a different graph representation. * - * @return The new representation of this graph + * @return + * The new representation of this graph. */ public Graph toGraph() { final Graph ret = new Graph<>(); @@ -193,10 +208,10 @@ public class AdjacencyMap { } /** - * Convert an adjacency map back into a stream + * Convert an adjacency map back into a stream. * * @param sink - * The stream to convert to + * The stream to convert to. */ public void toStream(final OutputStream sink) { if (sink == null) throw new NullPointerException("Output source must not be null"); diff --git a/base/src/main/java/bjc/utils/graph/Edge.java b/base/src/main/java/bjc/utils/graph/Edge.java index 0152e3d..9236464 100644 --- a/base/src/main/java/bjc/utils/graph/Edge.java +++ b/base/src/main/java/bjc/utils/graph/Edge.java @@ -1,38 +1,38 @@ package bjc.utils.graph; /** - * An edge in a weighted graph + * An edge in a weighted graph. * * @author ben * * @param - * The type of the nodes in the graph + * The type of the nodes in the graph. */ public class Edge { - /* - * The distance from initial to terminal node - */ + /* The distance from initial to terminal node. */ private final int distance; - /* - * The initial and terminal nodes of this edge - */ + /* The initial and terminal nodes of this edge. */ private final T source, target; /** - * Create a new edge with set parameters + * Create a new edge with set parameters. * * @param initial - * The initial node of the edge + * The initial node of the edge. + * * @param terminal - * The terminal node of the edge + * The terminal node of the edge. + * * @param distance - * The distance between initial and terminal edge + * The distance between initial and terminal edge. */ public Edge(final T initial, final T terminal, final int distance) { - if (initial == null) + if (initial == null) { throw new NullPointerException("Initial node must not be null"); - else if (terminal == null) throw new NullPointerException("Terminal node must not be null"); + } else if (terminal == null) { + throw new NullPointerException("Terminal node must not be null"); + } this.source = initial; this.target = terminal; @@ -65,28 +65,31 @@ public class Edge { } /** - * Get the distance in this edge + * Get the distance in this edge. * - * @return The distance between the initial and terminal nodes of this - * edge + * @return + * The distance between the initial and terminal nodes of this + * edge. */ public int getDistance() { return distance; } /** - * Get the initial node of an edge + * Get the initial node of an edge. * - * @return The initial node of this edge + * @return + * The initial node of this edge. */ public T getSource() { return source; } /** - * Get the target node of an edge + * Get the target node of an edge. * - * @return The target node of this edge + * @return + * The target node of this edge. */ public T getTarget() { return target; @@ -107,6 +110,9 @@ public class Edge { @Override public String toString() { - return " first vertex " + source + " to vertex " + target + " with distance: " + distance; + String msg = String.format("source vertex %s to target vertex %s with distance: %s", + source, target, distance); + + return msg; } } diff --git a/base/src/main/java/bjc/utils/graph/Graph.java b/base/src/main/java/bjc/utils/graph/Graph.java index 280a7f5..3e03919 100644 --- a/base/src/main/java/bjc/utils/graph/Graph.java +++ b/base/src/main/java/bjc/utils/graph/Graph.java @@ -17,23 +17,25 @@ import bjc.utils.funcdata.IList; import bjc.utils.funcdata.IMap; /** - * A directed weighted graph, where the vertices have some arbitrary label + * A directed weighted graph, where the vertices have some arbitrary label. * * @author ben * * @param - * The label for vertices + * The label for vertices. */ public class Graph { /** - * Create a graph from a list of edges + * Create a graph from a list of edges. * * @param - * The type of data stored in the edges + * The type of data stored in the edges. * * @param edges - * The list of edges to build from - * @return A graph built from the provided edge-list + * The list of edges to build from. + * + * @return + * A graph built from the provided edge-list. */ public static Graph fromEdgeList(final List> edges) { final Graph g = new Graph<>(); @@ -45,46 +47,46 @@ public class Graph { return g; } - /** - * The backing representation of the graph - */ + /** The backing representation of the graph. */ private final IMap> backing; - /** - * Create a new graph - */ + /** Create a new empty graph. */ public Graph() { backing = new FunctionalMap<>(); } /** - * Add a edge to the graph + * Add a edge to the graph. * * @param source - * The source vertex for this edge + * The source vertex for this edge. + * * @param target - * The target vertex for this edge + * The target vertex for this edge. + * * @param distance - * The distance from the source vertex to the target - * vertex + * The distance from the source vertex to the target vertex. + * * @param directed - * Whether or not + * Whether or not the edge is directed or not. */ public void addEdge(final T source, final T target, final int distance, final boolean directed) { - // Can't add edges with a null source or target - if (source == null) + /* Can't add edges with a null source or target. */ + if (source == null) { throw new NullPointerException("The source vertex cannot be null"); - else if (target == null) throw new NullPointerException("The target vertex cannot be null"); + } else if (target == null) { + throw new NullPointerException("The target vertex cannot be null"); + } - // Initialize adjacency list for vertices if necessary + /* Initialize adjacency list for vertices if necessary. */ if (!backing.containsKey(source)) { backing.put(source, new FunctionalMap()); } - // Add the edge to the graph + /* Add the edge to the graph. */ backing.get(source).put(target, distance); - // Handle possible directed edges + /* Handle possible directed edges. */ if (!directed) { if (!backing.containsKey(target)) { backing.put(target, new FunctionalMap()); @@ -96,20 +98,24 @@ public class Graph { /** * Execute an action for all edges of a specific vertex matching - * conditions + * conditions. * * @param source - * The vertex to test edges for + * The vertex to test edges for. + * * @param matcher - * The conditions an edge must match + * The conditions an edge must match. + * * @param action - * The action to execute for matching edges + * The action to execute for matching edges. */ public void forAllEdgesMatchingAt(final T source, final BiPredicate matcher, final BiConsumer action) { - if (matcher == null) + if (matcher == null) { throw new NullPointerException("Matcher must not be null"); - else if (action == null) throw new NullPointerException("Action must not be null"); + } else if (action == null) { + throw new NullPointerException("Action must not be null"); + } getEdges(source).forEach((target, weight) -> { if (matcher.test(target, weight)) { @@ -119,14 +125,15 @@ public class Graph { } /** - * Get all the edges that begin at a particular source vertex + * Get all the edges that begin at a particular source vertex. * * @param source - * The vertex to use as a source - * @return All of the edges with the specified vertex as a source + * The vertex to use as a source. + * @return + * All of the edges with the specified vertex as a source. */ public IMap getEdges(final T source) { - // Can't find edges for a null source + /* Can't find edges for a null source. */ if (source == null) throw new NullPointerException("The source cannot be null."); else if (!backing.containsKey(source)) @@ -136,9 +143,10 @@ public class Graph { } /** - * Get the initial vertex of the graph + * Get the initial vertex of the graph. * - * @return The initial vertex of the graph + * @return + * The initial vertex of the graph. */ public T getInitial() { return backing.keyList().first(); @@ -150,27 +158,28 @@ public class Graph { * If the graph is non-connected, this will lead to unpredictable * results. * - * @return a list of edges that constitute the MST + * @return + * A list of edges that constitute the MST. */ public List> getMinimumSpanningTree() { - // Set of all of the currently available edges + /* Set of all of the currently available edges. */ final Queue> available = new PriorityQueue<>(10, (left, right) -> left.getDistance() - right.getDistance()); - // The MST of the graph + /* The MST of the graph. */ final List> minimums = new ArrayList<>(); - // The set of all of the visited vertices. + /* The set of all of the visited vertices. */ final Set visited = new HashSet<>(); - // Start at the initial vertex and visit it + /* Start at the initial vertex and visit it */ final IHolder source = new Identity<>(getInitial()); visited.add(source.getValue()); - // Make sure we visit all the nodes + /* Make sure we visit all the nodes. */ while (visited.size() != getVertexCount()) { - // Grab all edges adjacent to the provided edge + /* Grab all edges adjacent to the provided edge. */ forAllEdgesMatchingAt(source.getValue(), (target, weight) -> { return !visited.contains(target); @@ -180,23 +189,24 @@ public class Graph { available.add(new Edge<>(vert, target, weight)); }); - // Get the edge with the minimum distance + /* Get the edge with the minimum distance. */ final IHolder> minimum = new Identity<>(available.poll()); - // Only consider edges where we haven't visited the - // target of - // the edge + /* + * Only consider edges where we haven't visited the + * target of the edge. + */ while (visited.contains(minimum.getValue().getTarget())) { minimum.transform((edge) -> available.poll()); } - // Add it to our MST + /* Add it to our MST. */ minimums.add(minimum.getValue()); - // Advance to the next node + /* Advance to the next node. */ source.transform((vertex) -> minimum.unwrap(edge -> edge.getTarget())); - // Visit this node + /* Visit this node. */ visited.add(source.getValue()); } @@ -204,9 +214,10 @@ public class Graph { } /** - * Get the count of the vertices in this graph + * Get the count of the vertices in this graph. * - * @return A count of the vertices in this graph + * @return + * A count of the vertices in this graph. */ public int getVertexCount() { return backing.size(); @@ -215,43 +226,56 @@ public class Graph { /** * Get all of the vertices in this graph. * - * @return A unmodifiable set of all the vertices in the graph. + * @return + * A unmodifiable set of all the vertices in the graph. */ public IList getVertices() { return backing.keyList(); } /** - * Remove the edge starting at the source and ending at the target + * Remove the edge starting at the source and ending at the target. * * @param source - * The source vertex for the edge + * The source vertex for the edge. + * * @param target - * The target vertex for the edge + * The target vertex for the edge. */ public void removeEdge(final T source, final T target) { - // Can't remove things w/ null vertices - if (source == null) + /* Can't remove things w/ null vertices. */ + if (source == null) { throw new NullPointerException("The source vertex cannot be null"); - else if (target == null) throw new NullPointerException("The target vertex cannot be null"); + } else if (target == null) { + throw new NullPointerException("The target vertex cannot be null"); + } - // Can't remove if one vertice doesn't exists - if (!backing.containsKey(source)) - throw new NoSuchElementException("vertex " + source + " does not exist."); + /* Can't remove if one vertice doesn't exists. */ + if (!backing.containsKey(source)) { + String msg = String.format("vertex %s does not exist", source); + + throw new NoSuchElementException(msg); + } - if (!backing.containsKey(target)) - throw new NoSuchElementException("vertex " + target + " does not exist."); + if (!backing.containsKey(target)) { + String msg = String.format("vertex %s does not exist", target); + + throw new NoSuchElementException(); + } backing.get(source).remove(target); - // Uncomment this to turn the graph undirected - // graph.get(target).remove(source); + /* Uncomment this to turn the graph undirected + * + * graph.get(target).remove(source); + */ } /** - * Convert a graph into a adjacency map/matrix + * Convert a graph into a adjacency map/matrix. * - * @return A adjacency map representing this graph + * @return + * A adjacency map representing this graph. */ public AdjacencyMap toAdjacencyMap() { final AdjacencyMap adjacency = new AdjacencyMap<>(backing.keyList()); -- cgit v1.2.3