From 275a627719fc2231b16caea41130ff09f0f2b6a1 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Fri, 8 Apr 2016 13:28:09 -0400 Subject: Switch functional data to use interfaces --- .../main/java/bjc/utils/funcutils/EnumUtils.java | 64 ++++++++++++++++++ .../main/java/bjc/utils/funcutils/FileUtils.java | 77 ++++++++++++++++++++++ .../main/java/bjc/utils/funcutils/FuncUtils.java | 44 +++++++++++++ .../main/java/bjc/utils/funcutils/ListUtils.java | 57 ++++++++-------- 4 files changed, 214 insertions(+), 28 deletions(-) create mode 100644 BJC-Utils2/src/main/java/bjc/utils/funcutils/EnumUtils.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/funcutils/FileUtils.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/funcutils/FuncUtils.java (limited to 'BJC-Utils2/src/main/java/bjc/utils/funcutils') diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/EnumUtils.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/EnumUtils.java new file mode 100644 index 0000000..f490727 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/EnumUtils.java @@ -0,0 +1,64 @@ +package bjc.utils.funcutils; + +import java.util.Random; +import java.util.function.Consumer; + +import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.IFunctionalList; + +/** + * Utility methods on enums + * + * @author ben + * + */ +public class EnumUtils { + /** + * Get a random value from an enum + * + * @param + * The type of the enum + * @param enumClass + * The class of the enum + * @param rnd + * The random source to use + * @return A random value from the specified enum + */ + public static > E getRandomValue(Class enumClass, + Random rnd) { + E[] enumValues = enumClass.getEnumConstants(); + + return new FunctionalList<>(enumValues).randItem(rnd); + } + + /** + * Do an action for a random number of enum values + * + * @param + * The type of the enum + * @param enumClass + * The enum class + * @param nValues + * The number of values to execute the action on + * @param action + * The action to perform on random values + * @param rnd + * The source of randomness to use + */ + public static > void doForValues(Class enumClass, + int nValues, Consumer action, Random rnd) { + E[] enumValues = enumClass.getEnumConstants(); + + IFunctionalList valueList = new FunctionalList<>(enumValues); + + int randomValueCount = enumValues.length - nValues; + + for (int i = 0; i <= randomValueCount; i++) { + E rDir = valueList.randItem(rnd); + + valueList.removeMatching(rDir); + } + + valueList.forEach(action); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/FileUtils.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/FileUtils.java new file mode 100644 index 0000000..fd09fbb --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/FileUtils.java @@ -0,0 +1,77 @@ +package bjc.utils.funcutils; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.function.BiPredicate; + +/** + * Utilities for doing things with files + * + * @author ben + * + */ +public class FileUtils { + private static final class FunctionalFileVisitor + extends SimpleFileVisitor { + private BiPredicate traversalPredicate; + private BiPredicate traversalAction; + + public FunctionalFileVisitor( + BiPredicate traversalPredicate, + BiPredicate traversalAction) { + this.traversalPredicate = traversalPredicate; + this.traversalAction = traversalAction; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) throws IOException { + if (traversalPredicate.test(dir, attrs)) { + return FileVisitResult.CONTINUE; + } + + return FileVisitResult.SKIP_SUBTREE; + } + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) throws IOException { + if (traversalAction.test(file, attrs)) { + return FileVisitResult.CONTINUE; + } + + return FileVisitResult.TERMINATE; + } + } + + /** + * Traverse a directory recursively. This is a depth-first traversal + * + * + * @param root + * The directory to start the traversal at + * @param traversalPredicate + * The predicate to determine whether or not to traverse a + * directory + * @param traversalAction + * 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 + * + * TODO If it becomes necessary, write another overload for + * this with all the buttons and knobs from walkFileTree + */ + public static void traverseDirectory(Path root, + BiPredicate traversalPredicate, + BiPredicate traversalAction) + throws IOException { + Files.walkFileTree(root, new FunctionalFileVisitor( + traversalPredicate, traversalAction)); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/FuncUtils.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/FuncUtils.java new file mode 100644 index 0000000..d89b7da --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/FuncUtils.java @@ -0,0 +1,44 @@ +package bjc.utils.funcutils; + +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.IntConsumer; + +/** + * Utility things for functions + * + * @author ben + * + */ +public class FuncUtils { + /** + * Do the specified action the specified number of times + * + * @param nTimes + * The number of times to do the action + * @param cons + * The action to perform + */ + public static void doTimes(int nTimes, IntConsumer cons) { + for (int i = 0; i < nTimes; i++) { + cons.accept(i); + } + } + + /** + * Convert a binary function into a unary function that returns a + * function + * + * @param The initial type of the function + * @param The intermediate type of the function + * @param The terminal type of the function + * @param func The function to transform + * @return The function transformed into a unary function returning a function + */ + public static Function> curry2( + BiFunction func) { + return (arg1) -> (arg2) -> { + return func.apply(arg1, arg2); + }; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java index 1d2750b..871e1cf 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java @@ -6,8 +6,9 @@ import java.util.function.Consumer; import java.util.function.Function; import bjc.utils.data.GenHolder; -import bjc.utils.data.Pair; +import bjc.utils.data.IPair; import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.IFunctionalList; /** * Utilities for manipulating FunctionalLists that don't belong in the @@ -20,7 +21,7 @@ public class ListUtils { private static final int MAX_NTRIESPART = 50; private static final class TokenDeaffixer - implements BiFunction> { + implements BiFunction> { private String token; public TokenDeaffixer(String tok) { @@ -28,7 +29,7 @@ public class ListUtils { } @Override - public FunctionalList apply(String operatorName, + public IFunctionalList apply(String operatorName, String operatorRegex) { if (operatorName == null) { throw new NullPointerException( @@ -53,7 +54,7 @@ public class ListUtils { } private static final class TokenSplitter - implements BiFunction> { + implements BiFunction> { private String tokenToSplit; public TokenSplitter(String tok) { @@ -61,7 +62,7 @@ public class ListUtils { } @Override - public FunctionalList apply(String operatorName, + public IFunctionalList apply(String operatorName, String operatorRegex) { if (operatorName == null) { throw new NullPointerException( @@ -77,10 +78,10 @@ public class ListUtils { return new FunctionalList<>(tokenToSplit); } - FunctionalList splitTokens = new FunctionalList<>( + IFunctionalList splitTokens = new FunctionalList<>( tokenToSplit.split(operatorRegex)); - FunctionalList result = new FunctionalList<>(); + IFunctionalList result = new FunctionalList<>(); int tokenExpansionSize = splitTokens.getSize(); @@ -112,17 +113,17 @@ public class ListUtils { */ private static final class GroupPartIteration implements Consumer { - private FunctionalList> returnedList; - private GenHolder> currentPartition; - private FunctionalList rejectedItems; + private IFunctionalList> returnedList; + private GenHolder> currentPartition; + private IFunctionalList rejectedItems; private GenHolder numberInCurrentPartition; private int numberPerPartition; private Function elementCounter; public GroupPartIteration( - FunctionalList> returned, - GenHolder> currPart, - FunctionalList rejects, + IFunctionalList> returned, + GenHolder> currPart, + IFunctionalList rejects, GenHolder numInCurrPart, int nPerPart, Function eleCount) { this.returnedList = returned; @@ -174,8 +175,8 @@ public class ListUtils { * The number of elements to put in each partition * @return A list partitioned according to the above rules */ - public static FunctionalList> groupPartition( - FunctionalList input, Function elementCounter, + public static IFunctionalList> groupPartition( + IFunctionalList input, Function elementCounter, int numberPerPartition) { if (input == null) { throw new NullPointerException("Input list must not be null"); @@ -192,17 +193,17 @@ public class ListUtils { /* * List that holds our results */ - FunctionalList> returnedList = new FunctionalList<>(); + IFunctionalList> returnedList = new FunctionalList<>(); /* * List that holds current partition */ - GenHolder> currentPartition = new GenHolder<>( + GenHolder> currentPartition = new GenHolder<>( new FunctionalList<>()); /* * List that holds elements rejected during current pass */ - FunctionalList rejectedElements = new FunctionalList<>(); + IFunctionalList rejectedElements = new FunctionalList<>(); /* * The effective number of elements in the current partitition @@ -251,9 +252,9 @@ public class ListUtils { * @return A list of tokens split on all the operators * */ - public static FunctionalList splitTokens( - FunctionalList input, - Deque> operators) { + public static IFunctionalList splitTokens( + IFunctionalList input, + Deque> operators) { if (input == null) { throw new NullPointerException("Input must not be null"); } else if (operators == null) { @@ -261,7 +262,7 @@ public class ListUtils { "Set of operators must not be null"); } - GenHolder> returnedList = new GenHolder<>( + GenHolder> returnedList = new GenHolder<>( input); operators.forEach((operator) -> returnedList @@ -282,9 +283,9 @@ public class ListUtils { * @return The tokens that have been deaffixed * */ - public static FunctionalList deAffixTokens( - FunctionalList input, - Deque> operators) { + public static IFunctionalList deAffixTokens( + IFunctionalList input, + Deque> operators) { if (input == null) { throw new NullPointerException("Input must not be null"); } else if (operators == null) { @@ -292,7 +293,7 @@ public class ListUtils { "Set of operators must not be null"); } - GenHolder> returnedList = new GenHolder<>( + GenHolder> returnedList = new GenHolder<>( input); operators.forEach((operator) -> returnedList @@ -311,7 +312,7 @@ public class ListUtils { * The list of tokens to collapse * @return The collapsed string of tokens */ - public static String collapseTokens(FunctionalList input) { + public static String collapseTokens(IFunctionalList input) { if (input == null) { throw new NullPointerException("Input must not be null"); } @@ -329,7 +330,7 @@ public class ListUtils { * The seperator to use for seperating tokens * @return The collapsed string of tokens */ - public static String collapseTokens(FunctionalList input, + public static String collapseTokens(IFunctionalList input, String seperator) { if (input == null) { throw new NullPointerException("Input must not be null"); -- cgit v1.2.3