summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/cli/DelegatingCommand.java29
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommand.java28
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java136
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java59
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java90
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java99
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/BoundLazyPair.java104
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/HalfBoundLazyPair.java93
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java (renamed from BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java)2
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/IPair.java (renamed from BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java)2
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/Identity.java (renamed from BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java)2
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java (renamed from BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java)94
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/LazyPair.java134
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/Pair.java (renamed from BJC-Utils2/src/main/java/bjc/utils/data/experimental/Pair.java)2
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/experimental/LazyPair.java317
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/package-info.java (renamed from BJC-Utils2/src/main/java/bjc/utils/data/experimental/package-info.java)2
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java96
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java13
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java138
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java8
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalMap.java11
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java100
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java46
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcutils/FileUtils.java35
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcutils/FunctionalFileVisitor.java41
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcutils/GroupPartIteration.java64
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java198
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java14
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenDeaffixer.java39
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenSplitter.java56
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/gen/RandomGrammar.java1
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java4
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/gen/WeightedRandom.java6
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java74
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java36
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/gui/ListParameterPanel.java23
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java116
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java13
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenTransformer.java94
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java99
40 files changed, 1413 insertions, 1105 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/DelegatingCommand.java b/BJC-Utils2/src/main/java/bjc/utils/cli/DelegatingCommand.java
new file mode 100644
index 0000000..76794cf
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/cli/DelegatingCommand.java
@@ -0,0 +1,29 @@
+package bjc.utils.cli;
+
+class DelegatingCommand implements ICommand {
+ private ICommand delegate;
+
+ public DelegatingCommand(ICommand delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public ICommandHandler getHandler() {
+ return delegate.getHandler();
+ }
+
+ @Override
+ public ICommandHelp getHelp() {
+ return delegate.getHelp();
+ }
+
+ @Override
+ public ICommand createAlias() {
+ return new DelegatingCommand(delegate);
+ }
+
+ @Override
+ public boolean isAlias() {
+ return true;
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommand.java b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommand.java
index 658a299..3c0aef6 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommand.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommand.java
@@ -7,34 +7,6 @@ package bjc.utils.cli;
*
*/
public class GenericCommand implements ICommand {
- private static class DelegatingCommand implements ICommand {
- private ICommand delegate;
-
- public DelegatingCommand(ICommand delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public ICommandHandler getHandler() {
- return delegate.getHandler();
- }
-
- @Override
- public ICommandHelp getHelp() {
- return delegate.getHelp();
- }
-
- @Override
- public ICommand createAlias() {
- return new DelegatingCommand(delegate);
- }
-
- @Override
- public boolean isAlias() {
- return true;
- }
- }
-
private ICommandHandler handler;
private ICommandHelp help;
diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java
index c52bb08..84b4d39 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java
@@ -49,64 +49,7 @@ public class GenericCommandMode implements ICommandMode {
defaultHandlers = new FunctionalMap<>(new TreeMap<>());
helpTopics = new FunctionalMap<>(new TreeMap<>());
- setupDefaultCommands(errorOutput);
- }
-
- private void setupDefaultCommands(Consumer<String> errorOutput) {
- defaultHandlers.put("list", new GenericCommand((args) -> {
- listCommands();
-
- return this;
- }, "list\tList available command",
- "Lists all of the commands available in this mode,"
- + " as well as the commands that are valid in any mode."));
-
- defaultHandlers.put("alias", new GenericCommand((args) -> {
- aliasCommands(args);
-
- return this;
- }, "alias\tAlias one command to another",
- "alias gives a command another name it can be invoked by. It is invoked"
- + " with two arguments, the name of the command to alias"
- + ", and the alias to give that command."));
-
- defaultHandlers.put("help", new GenericCommand((args) -> {
- if (args == null || args.length == 0) {
- // Invoke general help
- helpSummary();
- } else {
- // Invoke help for a command
- helpCommand(args[0]);
- }
-
- return this;
- }, "help\tConsult the help system",
- "help consults the internal help system."
- + " It can be invoked in two ways. Invoking it with no arguments"
- + " causes it to print out all the topics you can ask for details on,"
- + " while invoking it with the name of a topic will print the entry"
- + " for that topic"));
-
- addCommandAlias("help", "man");
-
- // Add commands handled in a upper layer
- defaultHandlers.put("clear", new GenericCommand((args) -> {
- errorOutput.accept(
- "ERROR: This console doesn't support screen clearing");
-
- return this;
- }, "clear\tClear the screen",
- "clear clears the screen of all the text on it,"
- + " and prepares a fresh prompt."));
-
- defaultHandlers.put("exit", new GenericCommand((args) -> {
- errorOutput.accept(
- "ERROR: This console doesn't support auto-exiting");
-
- return this;
- }, "exit\tExit the game",
- "exit first prompts the user to make sure they want to exit,"
- + " and if they affirm it, it quits"));
+ setupDefaultCommands();
}
/**
@@ -197,6 +140,68 @@ public class GenericCommandMode implements ICommandMode {
}
}
+ private GenericCommand buildAliasCommand() {
+ return new GenericCommand((args) -> {
+ aliasCommands(args);
+
+ return this;
+ }, "alias\tAlias one command to another",
+ "alias gives a command another name it can be invoked by. It is invoked"
+ + " with two arguments, the name of the command to alias"
+ + ", and the alias to give that command.");
+ }
+
+ private GenericCommand buildClearCommands() {
+ return new GenericCommand((args) -> {
+ errorOutput.accept(
+ "ERROR: This console doesn't support screen clearing");
+
+ return this;
+ }, "clear\tClear the screen",
+ "clear clears the screen of all the text on it,"
+ + " and prepares a fresh prompt.");
+ }
+
+ private GenericCommand buildExitCommand() {
+ return new GenericCommand((args) -> {
+ errorOutput.accept(
+ "ERROR: This console doesn't support auto-exiting");
+
+ return this;
+ }, "exit\tExit the game",
+ "exit first prompts the user to make sure they want to exit,"
+ + " and if they affirm it, it quits");
+ }
+
+ private GenericCommand buildHelpCommand() {
+ return new GenericCommand((args) -> {
+ if (args == null || args.length == 0) {
+ // Invoke general help
+ helpSummary();
+ } else {
+ // Invoke help for a command
+ helpCommand(args[0]);
+ }
+
+ return this;
+ }, "help\tConsult the help system",
+ "help consults the internal help system."
+ + " It can be invoked in two ways. Invoking it with no arguments"
+ + " causes it to print out all the topics you can ask for details on,"
+ + " while invoking it with the name of a topic will print the entry"
+ + " for that topic");
+ }
+
+ private GenericCommand buildListCommand() {
+ return new GenericCommand((args) -> {
+ listCommands();
+
+ return this;
+ }, "list\tList available command",
+ "Lists all of the commands available in this mode,"
+ + " as well as the commands that are valid in any mode.");
+ }
+
@Override
public boolean canHandleCommand(String command) {
return commandHandlers.containsKey(command)
@@ -359,6 +364,21 @@ public class GenericCommandMode implements ICommandMode {
unknownCommandHandler = handler;
}
+ private void setupDefaultCommands() {
+ defaultHandlers.put("list", buildListCommand());
+
+ defaultHandlers.put("alias", buildAliasCommand());
+
+ defaultHandlers.put("help", buildHelpCommand());
+
+ addCommandAlias("help", "man");
+
+ // Add commands handled in a upper layer
+ defaultHandlers.put("clear", buildClearCommands());
+
+ defaultHandlers.put("exit", buildExitCommand());
+ }
+
@Override
public boolean useCustomPrompt() {
return customPrompt != null;
diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java
index 254e380..eec3fa8 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java
@@ -1,8 +1,10 @@
package bjc.utils.components;
import java.io.InputStream;
+import java.util.function.BiConsumer;
import bjc.utils.exceptions.PragmaFormatException;
+import bjc.utils.funcdata.FunctionalStringTokenizer;
import bjc.utils.funcutils.ListUtils;
import bjc.utils.parserutils.RuleBasedConfigReader;
@@ -26,40 +28,21 @@ public class ComponentDescriptionFileParser {
// Don't need to do anything on rule end
});
- reader.addPragma("name", (tokenizer, state) -> {
- if (!tokenizer.hasMoreTokens()) {
- throw new PragmaFormatException(
- "Pragma name requires one string argument");
- }
-
- state.setName(ListUtils
- .collapseTokens(tokenizer.toList((strang) -> strang)));
- });
-
- reader.addPragma("author", (tokenizer, state) -> {
- if (!tokenizer.hasMoreTokens()) {
- throw new PragmaFormatException(
- "Pragma author requires one string argument");
- }
+ setupReaderPragmas();
+ }
- state.setAuthor(ListUtils
- .collapseTokens(tokenizer.toList((strang) -> strang)));
- });
+ private static void setupReaderPragmas() {
+ reader.addPragma("name", buildStringCollapserPragma("name"));
- reader.addPragma("description", (tokenizer, state) -> {
- if (!tokenizer.hasMoreTokens()) {
- throw new PragmaFormatException(
- "Pragma description requires one string argument");
- }
+ reader.addPragma("author", buildStringCollapserPragma("author"));
- state.setDescription(ListUtils
- .collapseTokens(tokenizer.toList((strang) -> strang)));
- });
+ reader.addPragma("description",
+ buildStringCollapserPragma("description"));
reader.addPragma("version", (tokenizer, state) -> {
if (!tokenizer.hasMoreTokens()) {
throw new PragmaFormatException(
- "Pragma name requires one integer argument");
+ "Pragma version requires one integer argument");
}
String token = tokenizer.nextToken();
@@ -67,8 +50,8 @@ public class ComponentDescriptionFileParser {
try {
state.setVersion(Integer.parseInt(token));
} catch (NumberFormatException nfex) {
- PragmaFormatException pfex = new PragmaFormatException(
- "Argument " + token
+ PragmaFormatException pfex =
+ new PragmaFormatException("Argument " + token
+ " to version pragma isn't a valid integer. "
+ "This pragma requires a integer argument");
@@ -79,6 +62,20 @@ public class ComponentDescriptionFileParser {
});
}
+ private static
+ BiConsumer<FunctionalStringTokenizer, ComponentDescriptionState>
+ buildStringCollapserPragma(String pragmaName) {
+ return (tokenizer, state) -> {
+ if (!tokenizer.hasMoreTokens()) {
+ throw new PragmaFormatException("Pragma " + pragmaName
+ + " requires one string argument");
+ }
+
+ state.setName(ListUtils
+ .collapseTokens(tokenizer.toList((strang) -> strang)));
+ };
+ }
+
/**
* Parse a component description from a stream
*
@@ -86,8 +83,8 @@ public class ComponentDescriptionFileParser {
* The stream to parse from
* @return The description parsed from the stream
*/
- public static ComponentDescription fromStream(
- InputStream inputSource) {
+ public static ComponentDescription
+ fromStream(InputStream inputSource) {
ComponentDescriptionState readState = reader
.fromStream(inputSource, new ComponentDescriptionState());
diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java b/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java
index 39a7eed..53219fb 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java
@@ -3,13 +3,15 @@ package bjc.utils.components;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.function.BiPredicate;
import java.util.function.Function;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import bjc.utils.data.experimental.IHolder;
-import bjc.utils.data.experimental.Identity;
+import bjc.utils.data.IHolder;
+import bjc.utils.data.Identity;
import bjc.utils.funcdata.FunctionalList;
import bjc.utils.funcdata.FunctionalMap;
import bjc.utils.funcdata.IFunctionalList;
@@ -28,8 +30,8 @@ import bjc.utils.funcutils.FileUtils;
public class FileComponentRepository<E extends IDescribedComponent>
implements IComponentRepository<E> {
- private static final Logger CLASS_LOGGER = LoggerFactory
- .getLogger(FileComponentRepository.class);
+ private static final Logger CLASS_LOGGER =
+ LoggerFactory.getLogger(FileComponentRepository.class);
/**
* The internal storage of components
@@ -68,49 +70,57 @@ public class FileComponentRepository<E extends IDescribedComponent>
IHolder<Boolean> isFirstDir = new Identity<>(true);
- try {
- FileUtils.traverseDirectory(sourceDirectory, (pth, attr) -> {
- if (attr.isDirectory() && !isFirstDir.getValue()) {
- // Don't skip the first directory, that's the parent
- isFirstDir.replace(false);
- // Skip directories, they probably have component
- return false;
- }
-
- return true;
- }, (pth, attr) -> {
- try {
- E component = componentReader.apply(pth.toFile());
-
- if (component == null) {
- throw new NullPointerException(
- "Component reader read null component");
- } else if (!components
- .containsKey(component.getName())) {
- components.put(component.getName(), component);
- } else {
- CLASS_LOGGER.warn("Found a duplicate component.\n"
- + "Multiple versions of the same component are not currently supported.\n"
- + "The component" + component
- + " will not be registered .");
+ BiPredicate<Path, BasicFileAttributes> firstLevelTraverser =
+ (pth, attr) -> {
+ if (attr.isDirectory() && !isFirstDir.getValue()) {
+ // Don't skip the first directory, that's the
+ // parent
+ isFirstDir.replace(false);
+ // Skip directories, they probably have
+ // component
+ return false;
}
- } catch (Exception ex) {
- CLASS_LOGGER.warn(
- "Error found reading component from file "
- + pth.toString()
- + ". This component will not be loaded",
- ex);
- }
-
- // Keep loading components, even if this one failed
- return true;
- });
+
+ return true;
+ };
+
+ try {
+ FileUtils.traverseDirectory(sourceDirectory,
+ firstLevelTraverser, (pth, attr) -> {
+ loadComponent(componentReader, pth);
+
+ // Keep loading components, even if this one failed
+ return true;
+ });
} catch (IOException ioex) {
CLASS_LOGGER.warn("Error found reading component from file.",
ioex);
}
}
+ private void loadComponent(Function<File, E> componentReader,
+ Path pth) {
+ try {
+ E component = componentReader.apply(pth.toFile());
+
+ if (component == null) {
+ throw new NullPointerException(
+ "Component reader read null component");
+ } else if (!components.containsKey(component.getName())) {
+ components.put(component.getName(), component);
+ } else {
+ CLASS_LOGGER.warn("Found a duplicate component.\n"
+ + "Multiple versions of the same component are not currently supported.\n"
+ + "The component" + component
+ + " will not be registered .");
+ }
+ } catch (Exception ex) {
+ CLASS_LOGGER.warn("Error found reading component from file "
+ + pth.toString()
+ + ". This component will not be loaded", ex);
+ }
+ }
+
@Override
public IFunctionalList<E> getComponentList() {
IFunctionalList<E> returnedList = new FunctionalList<>();
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java
new file mode 100644
index 0000000..dda65a7
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java
@@ -0,0 +1,99 @@
+package bjc.utils.data;
+
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+
+import bjc.utils.funcdata.FunctionalList;
+import bjc.utils.funcdata.IFunctionalList;
+
+class BoundLazy<OldType, BoundContainedType>
+ implements IHolder<BoundContainedType> {
+ private Supplier<IHolder<OldType>> oldSupplier;
+
+ private Function<OldType, IHolder<BoundContainedType>> binder;
+
+ private IHolder<BoundContainedType> boundHolder;
+
+ private boolean holderBound;
+
+ private IFunctionalList<UnaryOperator<BoundContainedType>> actions = new FunctionalList<>();
+
+ public BoundLazy(Supplier<IHolder<OldType>> supp,
+ Function<OldType, IHolder<BoundContainedType>> binder) {
+ oldSupplier = supp;
+ this.binder = binder;
+ }
+
+ @Override
+ public <BoundType> IHolder<BoundType> bind(
+ Function<BoundContainedType, IHolder<BoundType>> bindr) {
+ IFunctionalList<UnaryOperator<BoundContainedType>> pendingActions = new FunctionalList<>();
+
+ actions.forEach(pendingActions::add);
+
+ Supplier<IHolder<BoundContainedType>> typeSupplier = () -> {
+ IHolder<BoundContainedType> oldHolder = boundHolder;
+
+ if (!holderBound) {
+ oldHolder = oldSupplier.get().unwrap(binder);
+ }
+
+ return pendingActions.reduceAux(oldHolder, (action, state) -> {
+ return state.transform(action);
+ }, (value) -> value);
+ };
+
+ return new BoundLazy<>(typeSupplier, bindr);
+ }
+
+ @Override
+ public <MappedType> IHolder<MappedType> map(
+ Function<BoundContainedType, MappedType> mapper) {
+ IFunctionalList<UnaryOperator<BoundContainedType>> pendingActions = new FunctionalList<>();
+
+ actions.forEach(pendingActions::add);
+
+ Supplier<MappedType> typeSupplier = () -> {
+ IHolder<BoundContainedType> oldHolder = boundHolder;
+
+ if (!holderBound) {
+ oldHolder = oldSupplier.get().unwrap(binder);
+ }
+
+ return pendingActions.reduceAux(oldHolder.getValue(),
+ (action, state) -> {
+ return action.apply(state);
+ }, (value) -> mapper.apply(value));
+ };
+
+ return new Lazy<>(typeSupplier);
+ }
+
+ @Override
+ public IHolder<BoundContainedType> transform(
+ UnaryOperator<BoundContainedType> transformer) {
+ actions.add(transformer);
+
+ return this;
+ }
+
+ @Override
+ public <UnwrappedType> UnwrappedType unwrap(
+ Function<BoundContainedType, UnwrappedType> unwrapper) {
+ if (!holderBound) {
+ boundHolder = oldSupplier.get().unwrap(binder::apply);
+ }
+
+ return boundHolder.unwrap(unwrapper);
+ }
+
+ @Override
+ public String toString() {
+ if (holderBound) {
+ return boundHolder.toString();
+ }
+
+ return "(unmaterialized)";
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazyPair.java
new file mode 100644
index 0000000..41ab99b
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazyPair.java
@@ -0,0 +1,104 @@
+package bjc.utils.data;
+
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight>
+ implements IPair<NewLeft, NewRight> {
+ private Supplier<OldLeft> leftSupplier;
+ private Supplier<OldRight> rightSupplier;
+
+ private BiFunction<OldLeft, OldRight, IPair<NewLeft, NewRight>> binder;
+
+ private IPair<NewLeft, NewRight> boundPair;
+
+ private boolean pairBound;
+
+ public BoundLazyPair(Supplier<OldLeft> leftSupp,
+ Supplier<OldRight> rightSupp,
+ BiFunction<OldLeft, OldRight, IPair<NewLeft, NewRight>> bindr) {
+ leftSupplier = leftSupp;
+ rightSupplier = rightSupp;
+ binder = bindr;
+ }
+
+ @Override
+ public <BoundLeft> IPair<BoundLeft, NewRight> bindLeft(
+ Function<NewLeft, IPair<BoundLeft, NewRight>> leftBinder) {
+ Supplier<NewLeft> leftSupp = () -> {
+ IPair<NewLeft, NewRight> newPair = boundPair;
+
+ if (!pairBound) {
+ newPair = binder.apply(leftSupplier.get(),
+ rightSupplier.get());
+ }
+
+ return newPair.getLeft();
+ };
+
+ return new HalfBoundLazyPair<>(leftSupp, leftBinder);
+ }
+
+ @Override
+ public <BoundRight> IPair<NewLeft, BoundRight> bindRight(
+ Function<NewRight, IPair<NewLeft, BoundRight>> rightBinder) {
+ Supplier<NewRight> rightSupp = () -> {
+ IPair<NewLeft, NewRight> newPair = boundPair;
+
+ if (!pairBound) {
+ newPair = binder.apply(leftSupplier.get(),
+ rightSupplier.get());
+ }
+
+ return newPair.getRight();
+ };
+
+ return new HalfBoundLazyPair<>(rightSupp, rightBinder);
+ }
+
+ @Override
+ public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
+ BiFunction<NewLeft, NewRight, IPair<BoundLeft, BoundRight>> bindr) {
+ IHolder<IPair<NewLeft, NewRight>> newPair = new Identity<>(
+ boundPair);
+ IHolder<Boolean> newPairMade = new Identity<>(pairBound);
+
+ Supplier<NewLeft> leftSupp = () -> {
+ if (!newPairMade.getValue()) {
+ newPair.replace(binder.apply(leftSupplier.get(),
+ rightSupplier.get()));
+
+ newPairMade.replace(false);
+ }
+
+ return newPair.unwrap((pair) -> pair.getLeft());
+ };
+
+ Supplier<NewRight> rightSupp = () -> {
+ if (!newPairMade.getValue()) {
+ newPair.replace(binder.apply(leftSupplier.get(),
+ rightSupplier.get()));
+
+ newPairMade.replace(false);
+ }
+
+ return newPair.unwrap((pair) -> pair.getRight());
+ };
+
+ return new BoundLazyPair<>(leftSupp, rightSupp, bindr);
+ }
+
+ @Override
+ public <MergedType> MergedType merge(
+ BiFunction<NewLeft, NewRight, MergedType> merger) {
+ if (!pairBound) {
+ boundPair = binder.apply(leftSupplier.get(),
+ rightSupplier.get());
+
+ pairBound = true;
+ }
+
+ return boundPair.merge(merger);
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/HalfBoundLazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/HalfBoundLazyPair.java
new file mode 100644
index 0000000..f32f58f
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/HalfBoundLazyPair.java
@@ -0,0 +1,93 @@
+package bjc.utils.data;
+
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+class HalfBoundLazyPair<OldType, NewLeft, NewRight>
+ implements IPair<NewLeft, NewRight> {
+ private Supplier<OldType> oldSupplier;
+
+ private Function<OldType, IPair<NewLeft, NewRight>> binder;
+
+ private IPair<NewLeft, NewRight> boundPair;
+ private boolean pairBound;
+
+ public HalfBoundLazyPair(Supplier<OldType> oldSupp,
+ Function<OldType, IPair<NewLeft, NewRight>> bindr) {
+ oldSupplier = oldSupp;
+ binder = bindr;
+ }
+
+ @Override
+ public <BoundLeft> IPair<BoundLeft, NewRight> bindLeft(
+ Function<NewLeft, IPair<BoundLeft, NewRight>> leftBinder) {
+ Supplier<NewLeft> leftSupp = () -> {
+ IPair<NewLeft, NewRight> newPair = boundPair;
+
+ if (!pairBound) {
+ newPair = binder.apply(oldSupplier.get());
+ }
+
+ return newPair.getLeft();
+ };
+
+ return new HalfBoundLazyPair<>(leftSupp, leftBinder);
+ }
+
+ @Override
+ public <BoundRight> IPair<NewLeft, BoundRight> bindRight(
+ Function<NewRight, IPair<NewLeft, BoundRight>> rightBinder) {
+ Supplier<NewRight> rightSupp = () -> {
+ IPair<NewLeft, NewRight> newPair = boundPair;
+
+ if (!pairBound) {
+ newPair = binder.apply(oldSupplier.get());
+ }
+
+ return newPair.getRight();
+ };
+
+ return new HalfBoundLazyPair<>(rightSupp, rightBinder);
+ }
+
+ @Override
+ public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
+ BiFunction<NewLeft, NewRight, IPair<BoundLeft, BoundRight>> bindr) {
+ IHolder<IPair<NewLeft, NewRight>> newPair = new Identity<>(
+ boundPair);
+ IHolder<Boolean> newPairMade = new Identity<>(pairBound);
+
+ Supplier<NewLeft> leftSupp = () -> {
+ if (!newPairMade.getValue()) {
+ newPair.replace(binder.apply(oldSupplier.get()));
+ newPairMade.replace(true);
+ }
+
+ return newPair.unwrap((pair) -> pair.getLeft());
+ };
+
+ Supplier<NewRight> rightSupp = () -> {
+ if (!newPairMade.getValue()) {
+ newPair.replace(binder.apply(oldSupplier.get()));
+ newPairMade.replace(true);
+ }
+
+ return newPair.unwrap((pair) -> pair.getRight());
+ };
+
+ return new BoundLazyPair<>(leftSupp, rightSupp, bindr);
+ }
+
+ @Override
+ public <MergedType> MergedType merge(
+ BiFunction<NewLeft, NewRight, MergedType> merger) {
+ if (!pairBound) {
+ boundPair = binder.apply(oldSupplier.get());
+
+ pairBound = true;
+ }
+
+ return boundPair.merge(merger);
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java
index 6ccf115..77eb899 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java
@@ -1,4 +1,4 @@
-package bjc.utils.data.experimental;
+package bjc.utils.data;
import java.util.function.Consumer;
import java.util.function.Function;
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java
index f5ca240..3d4998c 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java
@@ -1,4 +1,4 @@
-package bjc.utils.data.experimental;
+package bjc.utils.data;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java b/BJC-Utils2/src/main/java/bjc/utils/data/Identity.java
index 1780f2d..dcc7bef 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/Identity.java
@@ -1,4 +1,4 @@
-package bjc.utils.data.experimental;
+package bjc.utils.data;
import java.util.function.Function;
import java.util.function.UnaryOperator;
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java
index 0d6fcef..f4bc24a 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java
@@ -1,4 +1,4 @@
-package bjc.utils.data.experimental;
+package bjc.utils.data;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -16,98 +16,6 @@ import bjc.utils.funcdata.IFunctionalList;
* @param <ContainedType>
*/
public class Lazy<ContainedType> implements IHolder<ContainedType> {
- private static class BoundLazy<OldType, BoundContainedType>
- implements IHolder<BoundContainedType> {
- private Supplier<IHolder<OldType>> oldSupplier;
-
- private Function<OldType, IHolder<BoundContainedType>> binder;
-
- private IHolder<BoundContainedType> boundHolder;
-
- private boolean holderBound;
-
- private IFunctionalList<UnaryOperator<BoundContainedType>> actions = new FunctionalList<>();
-
- public BoundLazy(Supplier<IHolder<OldType>> supp,
- Function<OldType, IHolder<BoundContainedType>> binder) {
- oldSupplier = supp;
- this.binder = binder;
- }
-
- @Override
- public <BoundType> IHolder<BoundType> bind(
- Function<BoundContainedType, IHolder<BoundType>> bindr) {
- IFunctionalList<UnaryOperator<BoundContainedType>> pendingActions = new FunctionalList<>();
-
- actions.forEach(pendingActions::add);
-
- Supplier<IHolder<BoundContainedType>> typeSupplier = () -> {
- IHolder<BoundContainedType> oldHolder = boundHolder;
-
- if (!holderBound) {
- oldHolder = oldSupplier.get().unwrap(binder);
- }
-
- return pendingActions.reduceAux(oldHolder,
- (action, state) -> {
- return state.transform(action);
- }, (value) -> value);
- };
-
- return new BoundLazy<>(typeSupplier, bindr);
- }
-
- @Override
- public <MappedType> IHolder<MappedType> map(
- Function<BoundContainedType, MappedType> mapper) {
- IFunctionalList<UnaryOperator<BoundContainedType>> pendingActions = new FunctionalList<>();
-
- actions.forEach(pendingActions::add);
-
- Supplier<MappedType> typeSupplier = () -> {
- IHolder<BoundContainedType> oldHolder = boundHolder;
-
- if (!holderBound) {
- oldHolder = oldSupplier.get().unwrap(binder);
- }
-
- return pendingActions.reduceAux(oldHolder.getValue(),
- (action, state) -> {
- return action.apply(state);
- }, (value) -> mapper.apply(value));
- };
-
- return new Lazy<>(typeSupplier);
- }
-
- @Override
- public IHolder<BoundContainedType> transform(
- UnaryOperator<BoundContainedType> transformer) {
- actions.add(transformer);
-
- return this;
- }
-
- @Override
- public <UnwrappedType> UnwrappedType unwrap(
- Function<BoundContainedType, UnwrappedType> unwrapper) {
- if (!holderBound) {
- boundHolder = oldSupplier.get().unwrap(binder::apply);
- }
-
- return boundHolder.unwrap(unwrapper);
- }
-
- @Override
- public String toString() {
- if (holderBound) {
- return boundHolder.toString();
- }
-
- return "(unmaterialized)";
- }
- }
-
private Supplier<ContainedType> valueSupplier;
private IFunctionalList<UnaryOperator<ContainedType>> actions = new FunctionalList<>();
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/LazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/LazyPair.java
new file mode 100644
index 0000000..fd432c1
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/LazyPair.java
@@ -0,0 +1,134 @@
+package bjc.utils.data;
+
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+/**
+ * A lazy implementation of a pair
+ *
+ * @author ben
+ *
+ * @param <LeftType>
+ * The type on the left side of the pair
+ * @param <RightType>
+ * The type on the right side of the pair
+ */
+public class LazyPair<LeftType, RightType>
+ implements IPair<LeftType, RightType> {
+ private LeftType leftValue;
+ private RightType rightValue;
+
+ private Supplier<LeftType> leftSupplier;
+ private Supplier<RightType> rightSupplier;
+
+ private boolean leftMaterialized;
+ private boolean rightMaterialized;
+
+ /**
+ * Create a new lazy pair, using the set value s
+ *
+ * @param leftVal
+ * The value for the left side of the pair
+ * @param rightVal
+ * The value for the right side of the pair
+ */
+ public LazyPair(LeftType leftVal, RightType rightVal) {
+ leftValue = leftVal;
+ rightValue = rightVal;
+
+ leftMaterialized = true;
+ rightMaterialized = true;
+ }
+
+ /**
+ * Create a new lazy pair from the given value sources
+ *
+ * @param leftSupp
+ * The source for a value on the left side of the pair
+ * @param rightSupp
+ * The source for a value on the right side of the pair
+ */
+ public LazyPair(Supplier<LeftType> leftSupp,
+ Supplier<RightType> rightSupp) {
+ leftSupplier = leftSupp;
+ rightSupplier = rightSupp;
+
+ leftMaterialized = false;
+ rightMaterialized = false;
+ }
+
+ @Override
+ public <BoundLeft> IPair<BoundLeft, RightType> bindLeft(
+ Function<LeftType, IPair<BoundLeft, RightType>> leftBinder) {
+ Supplier<LeftType> leftSupp = () -> {
+ if (leftMaterialized) {
+ return leftValue;
+ }
+
+ return leftSupplier.get();
+ };
+
+ return new HalfBoundLazyPair<>(leftSupp, leftBinder);
+ }
+
+ @Override
+ public <BoundRight> IPair<LeftType, BoundRight> bindRight(
+ Function<RightType, IPair<LeftType, BoundRight>> rightBinder) {
+ Supplier<RightType> rightSupp = () -> {
+ if (rightMaterialized) {
+ return rightValue;
+ }
+
+ return rightSupplier.get();
+ };
+
+ return new HalfBoundLazyPair<>(rightSupp, rightBinder);
+ }
+
+ @Override
+ public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
+ BiFunction<LeftType, RightType, IPair<BoundLeft, BoundRight>> binder) {
+ return new BoundLazyPair<>(leftSupplier, rightSupplier, binder);
+ }
+
+ @Override
+ public <MergedType> MergedType merge(
+ BiFunction<LeftType, RightType, MergedType> merger) {
+ if (!leftMaterialized) {
+ leftValue = leftSupplier.get();
+
+ leftMaterialized = true;
+ }
+
+ if (!rightMaterialized) {
+ rightValue = rightSupplier.get();
+
+ rightMaterialized = true;
+ }
+
+ return merger.apply(leftValue, rightValue);
+ }
+
+ @Override
+ public LeftType getLeft() {
+ if (!leftMaterialized) {
+ leftValue = leftSupplier.get();
+
+ leftMaterialized = true;
+ }
+
+ return leftValue;
+ }
+
+ @Override
+ public RightType getRight() {
+ if (!rightMaterialized) {
+ rightValue = rightSupplier.get();
+
+ rightMaterialized = true;
+ }
+
+ return rightValue;
+ }
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Pair.java b/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java
index 87378d7..958df40 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Pair.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java
@@ -1,4 +1,4 @@
-package bjc.utils.data.experimental;
+package bjc.utils.data;
import java.util.function.BiFunction;
import java.util.function.Function;
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/LazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/LazyPair.java
deleted file mode 100644
index 04a4b61..0000000
--- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/LazyPair.java
+++ /dev/null
@@ -1,317 +0,0 @@
-package bjc.utils.data.experimental;
-
-import java.util.function.BiFunction;
-import java.util.function.Function;
-import java.util.function.Supplier;
-
-/**
- * A lazy implementation of a pair
- *
- * @author ben
- *
- * @param <LeftType>
- * The type on the left side of the pair
- * @param <RightType>
- * The type on the right side of the pair
- */
-public class LazyPair<LeftType, RightType>
- implements IPair<LeftType, RightType> {
- private static class HalfBoundLazyPair<OldType, NewLeft, NewRight>
- implements IPair<NewLeft, NewRight> {
- private Supplier<OldType> oldSupplier;
-
- private Function<OldType, IPair<NewLeft, NewRight>> binder;
-
- private IPair<NewLeft, NewRight> boundPair;
- private boolean pairBound;
-
- public HalfBoundLazyPair(Supplier<OldType> oldSupp,
- Function<OldType, IPair<NewLeft, NewRight>> bindr) {
- oldSupplier = oldSupp;
- binder = bindr;
- }
-
- @Override
- public <BoundLeft> IPair<BoundLeft, NewRight> bindLeft(
- Function<NewLeft, IPair<BoundLeft, NewRight>> leftBinder) {
- Supplier<NewLeft> leftSupp = () -> {
- IPair<NewLeft, NewRight> newPair = boundPair;
-
- if (!pairBound) {
- newPair = binder.apply(oldSupplier.get());
- }
-
- return newPair.getLeft();
- };
-
- return new HalfBoundLazyPair<>(leftSupp, leftBinder);
- }
-
- @Override
- public <BoundRight> IPair<NewLeft, BoundRight> bindRight(
- Function<NewRight, IPair<NewLeft, BoundRight>> rightBinder) {
- Supplier<NewRight> rightSupp = () -> {
- IPair<NewLeft, NewRight> newPair = boundPair;
-
- if (!pairBound) {
- newPair = binder.apply(oldSupplier.get());
- }
-
- return newPair.getRight();
- };
-
- return new HalfBoundLazyPair<>(rightSupp, rightBinder);
- }
-
- @Override
- public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
- BiFunction<NewLeft, NewRight, IPair<BoundLeft, BoundRight>> bindr) {
- IHolder<IPair<NewLeft, NewRight>> newPair = new Identity<>(
- boundPair);
- IHolder<Boolean> newPairMade = new Identity<>(pairBound);
-
- Supplier<NewLeft> leftSupp = () -> {
- if (!newPairMade.getValue()) {
- newPair.replace(binder.apply(oldSupplier.get()));
- newPairMade.replace(true);
- }
-
- return newPair.unwrap((pair) -> pair.getLeft());
- };
-
- Supplier<NewRight> rightSupp = () -> {
- if (!newPairMade.getValue()) {
- newPair.replace(binder.apply(oldSupplier.get()));
- newPairMade.replace(true);
- }
-
- return newPair.unwrap((pair) -> pair.getRight());
- };
-
- return new BoundLazyPair<>(leftSupp, rightSupp, bindr);
- }
-
- @Override
- public <MergedType> MergedType merge(
- BiFunction<NewLeft, NewRight, MergedType> merger) {
- if (!pairBound) {
- boundPair = binder.apply(oldSupplier.get());
-
- pairBound = true;
- }
-
- return boundPair.merge(merger);
- }
- }
-
- private static class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight>
- implements IPair<NewLeft, NewRight> {
- private Supplier<OldLeft> leftSupplier;
- private Supplier<OldRight> rightSupplier;
-
- private BiFunction<OldLeft, OldRight, IPair<NewLeft, NewRight>> binder;
-
- private IPair<NewLeft, NewRight> boundPair;
-
- private boolean pairBound;
-
- public BoundLazyPair(Supplier<OldLeft> leftSupp,
- Supplier<OldRight> rightSupp,
- BiFunction<OldLeft, OldRight, IPair<NewLeft, NewRight>> bindr) {
- leftSupplier = leftSupp;
- rightSupplier = rightSupp;
- binder = bindr;
- }
-
- @Override
- public <BoundLeft> IPair<BoundLeft, NewRight> bindLeft(
- Function<NewLeft, IPair<BoundLeft, NewRight>> leftBinder) {
- Supplier<NewLeft> leftSupp = () -> {
- IPair<NewLeft, NewRight> newPair = boundPair;
-
- if (!pairBound) {
- newPair = binder.apply(leftSupplier.get(),
- rightSupplier.get());
- }
-
- return newPair.getLeft();
- };
-
- return new HalfBoundLazyPair<>(leftSupp, leftBinder);
- }
-
- @Override
- public <BoundRight> IPair<NewLeft, BoundRight> bindRight(
- Function<NewRight, IPair<NewLeft, BoundRight>> rightBinder) {
- Supplier<NewRight> rightSupp = () -> {
- IPair<NewLeft, NewRight> newPair = boundPair;
-
- if (!pairBound) {
- newPair = binder.apply(leftSupplier.get(),
- rightSupplier.get());
- }
-
- return newPair.getRight();
- };
-
- return new HalfBoundLazyPair<>(rightSupp, rightBinder);
- }
-
- @Override
- public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
- BiFunction<NewLeft, NewRight, IPair<BoundLeft, BoundRight>> bindr) {
- IHolder<IPair<NewLeft, NewRight>> newPair = new Identity<>(
- boundPair);
- IHolder<Boolean> newPairMade = new Identity<>(pairBound);
-
- return new BoundLazyPair<>(() -> {
- if (!newPairMade.getValue()) {
- newPair.replace(binder.apply(leftSupplier.get(),
- rightSupplier.get()));
-
- newPairMade.replace(false);
- }
-
- return newPair.unwrap((pair) -> pair.getLeft());
- }, () -> {
- if (!newPairMade.getValue()) {
- newPair.replace(binder.apply(leftSupplier.get(),
- rightSupplier.get()));
-
- newPairMade.replace(false);
- }
-
- return newPair.unwrap((pair) -> pair.getRight());
- }, bindr);
- }
-
- @Override
- public <MergedType> MergedType merge(
- BiFunction<NewLeft, NewRight, MergedType> merger) {
- if (!pairBound) {
- boundPair = binder.apply(leftSupplier.get(),
- rightSupplier.get());
-
- pairBound = true;
- }
-
- return boundPair.merge(merger);
- }
- }
-
- private LeftType leftValue;
- private RightType rightValue;
-
- private Supplier<LeftType> leftSupplier;
- private Supplier<RightType> rightSupplier;
-
- private boolean leftMaterialized;
- private boolean rightMaterialized;
-
- /**
- * Create a new lazy pair, using the set value s
- *
- * @param leftVal
- * The value for the left side of the pair
- * @param rightVal
- * The value for the right side of the pair
- */
- public LazyPair(LeftType leftVal, RightType rightVal) {
- leftValue = leftVal;
- rightValue = rightVal;
-
- leftMaterialized = true;
- rightMaterialized = true;
- }
-
- /**
- * Create a new lazy pair from the given value sources
- *
- * @param leftSupp
- * The source for a value on the left side of the pair
- * @param rightSupp
- * The source for a value on the right side of the pair
- */
- public LazyPair(Supplier<LeftType> leftSupp,
- Supplier<RightType> rightSupp) {
- leftSupplier = leftSupp;
- rightSupplier = rightSupp;
-
- leftMaterialized = false;
- rightMaterialized = false;
- }
-
- @Override
- public <BoundLeft> IPair<BoundLeft, RightType> bindLeft(
- Function<LeftType, IPair<BoundLeft, RightType>> leftBinder) {
- Supplier<LeftType> leftSupp = () -> {
- if (leftMaterialized) {
- return leftValue;
- }
-
- return leftSupplier.get();
- };
-
- return new HalfBoundLazyPair<>(leftSupp, leftBinder);
- }
-
- @Override
- public <BoundRight> IPair<LeftType, BoundRight> bindRight(
- Function<RightType, IPair<LeftType, BoundRight>> rightBinder) {
- Supplier<RightType> rightSupp = () -> {
- if (rightMaterialized) {
- return rightValue;
- }
-
- return rightSupplier.get();
- };
-
- return new HalfBoundLazyPair<>(rightSupp, rightBinder);
- }
-
- @Override
- public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
- BiFunction<LeftType, RightType, IPair<BoundLeft, BoundRight>> binder) {
- return new BoundLazyPair<>(leftSupplier, rightSupplier, binder);
- }
-
- @Override
- public <MergedType> MergedType merge(
- BiFunction<LeftType, RightType, MergedType> merger) {
- if (!leftMaterialized) {
- leftValue = leftSupplier.get();
-
- leftMaterialized = true;
- }
-
- if (!rightMaterialized) {
- rightValue = rightSupplier.get();
-
- rightMaterialized = true;
- }
-
- return merger.apply(leftValue, rightValue);
- }
-
- @Override
- public LeftType getLeft() {
- if (!leftMaterialized) {
- leftValue = leftSupplier.get();
-
- leftMaterialized = true;
- }
-
- return leftValue;
- }
-
- @Override
- public RightType getRight() {
- if (!rightMaterialized) {
- rightValue = rightSupplier.get();
-
- rightMaterialized = true;
- }
-
- return rightValue;
- }
-}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/package-info.java b/BJC-Utils2/src/main/java/bjc/utils/data/package-info.java
index 72e1007..a6f05dd 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/package-info.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/package-info.java
@@ -4,4 +4,4 @@
* @author ben
*
*/
-package bjc.utils.data.experimental; \ No newline at end of file
+package bjc.utils.data; \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java
new file mode 100644
index 0000000..7e4c7fd
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java
@@ -0,0 +1,96 @@
+package bjc.utils.funcdata;
+
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import bjc.utils.funcutils.ListUtils;
+
+class ExtendedMap<KeyType, ValueType>
+ implements IFunctionalMap<KeyType, ValueType> {
+ private IFunctionalMap<KeyType, ValueType> delegate;
+
+ private IFunctionalMap<KeyType, ValueType> store;
+
+ public ExtendedMap(IFunctionalMap<KeyType, ValueType> delegate,
+ IFunctionalMap<KeyType, ValueType> store) {
+ this.delegate = delegate;
+ this.store = store;
+ }
+
+ @Override
+ public ValueType put(KeyType key, ValueType val) {
+ return store.put(key, val);
+ }
+
+ @Override
+ public ValueType get(KeyType key) {
+ if (store.containsKey(key)) {
+ return store.get(key);
+ }
+
+ return delegate.get(key);
+ }
+
+ @Override
+ public <MappedValue> IFunctionalMap<KeyType, MappedValue> mapValues(
+ Function<ValueType, MappedValue> transformer) {
+ return new TransformedValueMap<>(this, transformer);
+ }
+
+ @Override
+ public boolean containsKey(KeyType key) {
+ if (store.containsKey(key)) {
+ return true;
+ }
+
+ return delegate.containsKey(key);
+ }
+
+ @Override
+ public IFunctionalList<KeyType> keyList() {
+ return ListUtils.mergeLists(store.keyList(), delegate.keyList());
+ }
+
+ @Override
+ public void forEach(BiConsumer<KeyType, ValueType> action) {
+ store.forEach(action);
+
+ delegate.forEach(action);
+ }
+
+ @Override
+ public ValueType remove(KeyType key) {
+ return store.remove(key);
+ }
+
+ @Override
+ public int getSize() {
+ return store.getSize() + delegate.getSize();
+ }
+
+ @Override
+ public void forEachKey(Consumer<KeyType> action) {
+ store.forEachKey(action);
+
+ delegate.forEachKey(action);
+ }
+
+ @Override
+ public void forEachValue(Consumer<ValueType> action) {
+ store.forEachValue(action);
+
+ delegate.forEachValue(action);
+ }
+
+ @Override
+ public IFunctionalList<ValueType> valueList() {
+ return ListUtils.mergeLists(store.valueList(),
+ delegate.valueList());
+ }
+
+ @Override
+ public IFunctionalMap<KeyType, ValueType> extend() {
+ return new ExtendedMap<>(this, new FunctionalMap<>());
+ }
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java
index 9b388b2..70d04cc 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java
@@ -11,10 +11,10 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
-import bjc.utils.data.experimental.IHolder;
-import bjc.utils.data.experimental.IPair;
-import bjc.utils.data.experimental.Identity;
-import bjc.utils.data.experimental.Pair;
+import bjc.utils.data.IHolder;
+import bjc.utils.data.IPair;
+import bjc.utils.data.Identity;
+import bjc.utils.data.Pair;
import java.util.ArrayList;
@@ -590,4 +590,9 @@ public class FunctionalList<E> implements Cloneable, IFunctionalList<E> {
public E[] toArray(E[] arrType) {
return wrappedList.toArray(arrType);
}
+
+ @Override
+ public IFunctionalList<E> tail() {
+ return new FunctionalList<>(wrappedList.subList(1, getSize()));
+ }
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java
index da30064..eaa425b 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java
@@ -6,110 +6,21 @@ import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
-import bjc.utils.data.experimental.IPair;
+import bjc.utils.data.IPair;
/**
* Basic implementation of {@link IFunctionalMap}
*
* @author ben
*
- * @param <K>
+ * @param <KeyType>
* The type of the map's keys
- * @param <V>
+ * @param <ValueType>
* The type of the map's values
*/
-public class FunctionalMap<K, V> implements IFunctionalMap<K, V> {
- /**
- * A map that transforms values from one type to another
- *
- * @author ben
- *
- * @param <K>
- * The type of the map's keys
- * @param <V>
- * The type of the map's values
- * @param <V2>
- * The type of the transformed values
- */
- private static final class TransformedValueMap<K, V, V2>
- implements IFunctionalMap<K, V2> {
- private IFunctionalMap<K, V> mapToTransform;
- private Function<V, V2> transformer;
-
- public TransformedValueMap(IFunctionalMap<K, V> destMap,
- Function<V, V2> transform) {
- mapToTransform = destMap;
- transformer = transform;
- }
-
- @Override
- public V2 get(K key) {
- return transformer.apply(mapToTransform.get(key));
- }
-
- @Override
- public boolean containsKey(K key) {
- return mapToTransform.containsKey(key);
- }
-
- @Override
- public String toString() {
- return mapToTransform.toString();
- }
-
- @Override
- public V2 put(K key, V2 val) {
- throw new UnsupportedOperationException(
- "Can't add items to transformed map");
- }
-
- @Override
- public <V3> IFunctionalMap<K, V3> mapValues(
- Function<V2, V3> transform) {
- return new TransformedValueMap<>(this, transform);
- }
-
- @Override
- public IFunctionalList<K> keyList() {
- return mapToTransform.keyList();
- }
-
- @Override
- public void forEach(BiConsumer<K, V2> action) {
- mapToTransform.forEach((key, val) -> {
- action.accept(key, transformer.apply(val));
- });
- }
-
- @Override
- public V2 remove(K key) {
- return transformer.apply(mapToTransform.remove(key));
- }
-
- @Override
- public int getSize() {
- return mapToTransform.getSize();
- }
-
- @Override
- public void forEachKey(Consumer<K> action) {
- mapToTransform.forEachKey(action);
- }
-
- @Override
- public void forEachValue(Consumer<V2> action) {
- mapToTransform.forEachValue((val) -> {
- action.accept(transformer.apply(val));
- });
- }
-
- @Override
- public IFunctionalList<V2> valueList() {
- return mapToTransform.valueList().map(transformer);
- }
- }
-
- private Map<K, V> wrappedMap;
+public class FunctionalMap<KeyType, ValueType>
+ implements IFunctionalMap<KeyType, ValueType> {
+ private Map<KeyType, ValueType> wrappedMap;
/**
* Create a new blank functional map
@@ -124,7 +35,7 @@ public class FunctionalMap<K, V> implements IFunctionalMap<K, V> {
* @param wrap
* The map to wrap
*/
- public FunctionalMap(Map<K, V> wrap) {
+ public FunctionalMap(Map<KeyType, ValueType> wrap) {
if (wrap == null) {
throw new NullPointerException("Map to wrap must not be null");
}
@@ -139,10 +50,10 @@ public class FunctionalMap<K, V> implements IFunctionalMap<K, V> {
* The entries to put into the map
*/
@SafeVarargs
- public FunctionalMap(IPair<K, V>... entries) {
+ public FunctionalMap(IPair<KeyType, ValueType>... entries) {
this();
- for (IPair<K, V> entry : entries) {
+ for (IPair<KeyType, ValueType> entry : entries) {
entry.doWith((key, val) -> {
wrappedMap.put(key, val);
});
@@ -155,7 +66,7 @@ public class FunctionalMap<K, V> implements IFunctionalMap<K, V> {
* @see bjc.utils.funcdata.IFunctionalMap#put(K, V)
*/
@Override
- public V put(K key, V val) {
+ public ValueType put(KeyType key, ValueType val) {
if (key == null) {
throw new NullPointerException("Key must not be null");
}
@@ -169,7 +80,7 @@ public class FunctionalMap<K, V> implements IFunctionalMap<K, V> {
* @see bjc.utils.funcdata.IFunctionalMap#get(K)
*/
@Override
- public V get(K key) {
+ public ValueType get(KeyType key) {
if (key == null) {
throw new NullPointerException("Key must not be null");
}
@@ -189,8 +100,8 @@ public class FunctionalMap<K, V> implements IFunctionalMap<K, V> {
* Function)
*/
@Override
- public <V2> IFunctionalMap<K, V2> mapValues(
- Function<V, V2> transformer) {
+ public <MappedValue> IFunctionalMap<KeyType, MappedValue> mapValues(
+ Function<ValueType, MappedValue> transformer) {
if (transformer == null) {
throw new NullPointerException("Transformer must not be null");
}
@@ -204,7 +115,7 @@ public class FunctionalMap<K, V> implements IFunctionalMap<K, V> {
* @see bjc.utils.funcdata.IFunctionalMap#containsKey(K)
*/
@Override
- public boolean containsKey(K key) {
+ public boolean containsKey(KeyType key) {
return wrappedMap.containsKey(key);
}
@@ -214,8 +125,8 @@ public class FunctionalMap<K, V> implements IFunctionalMap<K, V> {
}
@Override
- public IFunctionalList<K> keyList() {
- FunctionalList<K> keys = new FunctionalList<>();
+ public IFunctionalList<KeyType> keyList() {
+ FunctionalList<KeyType> keys = new FunctionalList<>();
wrappedMap.keySet().forEach((key) -> {
keys.add(key);
@@ -225,12 +136,12 @@ public class FunctionalMap<K, V> implements IFunctionalMap<K, V> {
}
@Override
- public void forEach(BiConsumer<K, V> action) {
+ public void forEach(BiConsumer<KeyType, ValueType> action) {
wrappedMap.forEach(action);
}
@Override
- public V remove(K key) {
+ public ValueType remove(KeyType key) {
return wrappedMap.remove(key);
}
@@ -240,18 +151,18 @@ public class FunctionalMap<K, V> implements IFunctionalMap<K, V> {
}
@Override
- public void forEachKey(Consumer<K> action) {
+ public void forEachKey(Consumer<KeyType> action) {
wrappedMap.keySet().forEach(action);
}
@Override
- public void forEachValue(Consumer<V> action) {
+ public void forEachValue(Consumer<ValueType> action) {
wrappedMap.values().forEach(action);
}
@Override
- public IFunctionalList<V> valueList() {
- FunctionalList<V> values = new FunctionalList<>();
+ public IFunctionalList<ValueType> valueList() {
+ FunctionalList<ValueType> values = new FunctionalList<>();
wrappedMap.values().forEach((value) -> {
values.add(value);
@@ -259,4 +170,9 @@ public class FunctionalMap<K, V> implements IFunctionalMap<K, V> {
return values;
}
+
+ @Override
+ public IFunctionalMap<KeyType, ValueType> extend() {
+ return new ExtendedMap<>(this, new FunctionalMap<>());
+ }
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java
index 4be7277..f22df57 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java
@@ -7,7 +7,7 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
-import bjc.utils.data.experimental.IPair;
+import bjc.utils.data.IPair;
/**
* A wrapper over another list that provides eager functional operations
@@ -325,4 +325,10 @@ public interface IFunctionalList<ContainedType> {
* @return An iterable view onto the list
*/
Iterable<ContainedType> toIterable();
+
+ /**
+ * Get the tail of this list (the list without the first element
+ * @return The list without the first element
+ */
+ public IFunctionalList<ContainedType> tail();
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalMap.java
index c5fe559..0c96a9f 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalMap.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalMap.java
@@ -58,7 +58,8 @@ public interface IFunctionalMap<KeyType, ValueType> {
* The function to use to transform values
* @return The map where each value will be transformed after lookup
*/
- <V2> IFunctionalMap<KeyType, V2> mapValues(Function<ValueType, V2> transformer);
+ <V2> IFunctionalMap<KeyType, V2> mapValues(
+ Function<ValueType, V2> transformer);
/**
* Check if this map contains the specified key
@@ -125,4 +126,12 @@ public interface IFunctionalMap<KeyType, ValueType> {
* @return A list of values in this map
*/
IFunctionalList<ValueType> valueList();
+
+ /**
+ * Extends this map, creating a new map that will delegate queries to
+ * the map, but store any added values itself
+ *
+ * @return An extended map
+ */
+ IFunctionalMap<KeyType, ValueType> extend();
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java
new file mode 100644
index 0000000..75557fa
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java
@@ -0,0 +1,100 @@
+package bjc.utils.funcdata;
+
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * A map that transforms values from one type to another
+ *
+ * @author ben
+ *
+ * @param <OldKey>
+ * The type of the map's keys
+ * @param <OldValue>
+ * The type of the map's values
+ * @param <NewValue>
+ * The type of the transformed values
+ */
+final class TransformedValueMap<OldKey, OldValue, NewValue>
+ implements IFunctionalMap<OldKey, NewValue> {
+ private IFunctionalMap<OldKey, OldValue> mapToTransform;
+ private Function<OldValue, NewValue> transformer;
+
+ public TransformedValueMap(IFunctionalMap<OldKey, OldValue> destMap,
+ Function<OldValue, NewValue> transform) {
+ mapToTransform = destMap;
+ transformer = transform;
+ }
+
+ @Override
+ public NewValue get(OldKey key) {
+ return transformer.apply(mapToTransform.get(key));
+ }
+
+ @Override
+ public boolean containsKey(OldKey key) {
+ return mapToTransform.containsKey(key);
+ }
+
+ @Override
+ public String toString() {
+ return mapToTransform.toString();
+ }
+
+ @Override
+ public NewValue put(OldKey key, NewValue val) {
+ throw new UnsupportedOperationException(
+ "Can't add items to transformed map");
+ }
+
+ @Override
+ public <MappedValue> IFunctionalMap<OldKey, MappedValue> mapValues(
+ Function<NewValue, MappedValue> transform) {
+ return new TransformedValueMap<>(this, transform);
+ }
+
+ @Override
+ public IFunctionalList<OldKey> keyList() {
+ return mapToTransform.keyList();
+ }
+
+ @Override
+ public void forEach(BiConsumer<OldKey, NewValue> action) {
+ mapToTransform.forEach((key, val) -> {
+ action.accept(key, transformer.apply(val));
+ });
+ }
+
+ @Override
+ public NewValue remove(OldKey key) {
+ return transformer.apply(mapToTransform.remove(key));
+ }
+
+ @Override
+ public int getSize() {
+ return mapToTransform.getSize();
+ }
+
+ @Override
+ public void forEachKey(Consumer<OldKey> action) {
+ mapToTransform.forEachKey(action);
+ }
+
+ @Override
+ public void forEachValue(Consumer<NewValue> action) {
+ mapToTransform.forEachValue((val) -> {
+ action.accept(transformer.apply(val));
+ });
+ }
+
+ @Override
+ public IFunctionalList<NewValue> valueList() {
+ return mapToTransform.valueList().map(transformer);
+ }
+
+ @Override
+ public IFunctionalMap<OldKey, NewValue> extend() {
+ return new ExtendedMap<>(this, new FunctionalMap<>());
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java
index d9938d4..5ee4200 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java
@@ -6,6 +6,7 @@ import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import bjc.utils.funcdata.bst.TreeLinearizationMethod;
+import bjc.utils.funcutils.StringUtils;
/**
* A node in a homogenous tree.
@@ -119,11 +120,11 @@ public class Tree<ContainedType> implements ITree<ContainedType> {
Function<ContainedType, NewType> leafTransform,
Function<ContainedType, Function<IFunctionalList<NewType>, NewType>> nodeCollapser) {
if (hasChildren) {
- Function<IFunctionalList<NewType>, NewType> nodeTransformer = nodeCollapser
- .apply(data);
+ Function<IFunctionalList<NewType>, NewType> nodeTransformer =
+ nodeCollapser.apply(data);
- IFunctionalList<NewType> collapsedChildren = children
- .map((child) -> {
+ IFunctionalList<NewType> collapsedChildren =
+ children.map((child) -> {
return child.collapse(leafTransform, nodeCollapser,
(subTreeVal) -> subTreeVal);
});
@@ -164,8 +165,9 @@ public class Tree<ContainedType> implements ITree<ContainedType> {
public <MappedType> ITree<MappedType> transformTree(
Function<ContainedType, MappedType> transformer) {
if (hasChildren) {
- IFunctionalList<ITree<MappedType>> transformedChildren = children
- .map((child) -> child.transformTree(transformer));
+ IFunctionalList<ITree<MappedType>> transformedChildren =
+ children.map(
+ (child) -> child.transformTree(transformer));
return new Tree<>(transformer.apply(data),
transformedChildren);
@@ -219,8 +221,8 @@ public class Tree<ContainedType> implements ITree<ContainedType> {
Function<ContainedType, MappedType> leafTransformer,
Function<ContainedType, MappedType> operatorTransformer) {
if (hasChildren) {
- IFunctionalList<ITree<MappedType>> mappedChildren = children
- .map((child) -> {
+ IFunctionalList<ITree<MappedType>> mappedChildren =
+ children.map((child) -> {
return child.rebuildTree(leafTransformer,
operatorTransformer);
});
@@ -232,4 +234,32 @@ public class Tree<ContainedType> implements ITree<ContainedType> {
return new Tree<>(leafTransformer.apply(data));
}
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+
+ internalToString(builder, 1, true);
+
+ builder.deleteCharAt(builder.length() - 1);
+
+ return builder.toString();
+ }
+
+ protected void internalToString(StringBuilder builder, int indentLevel,
+ boolean initial) {
+ if (!initial) {
+ StringUtils.indentNLevels(builder, indentLevel);
+ }
+
+ builder.append("Node: ");
+ builder.append(data == null ? "(null)" : data.toString());
+ builder.append("\n");
+
+ if (hasChildren) {
+ children.forEach((child) -> {
+ ((Tree<ContainedType>) child).internalToString(builder,
+ indentLevel + 2, false);
+ });
+ }
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/FileUtils.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/FileUtils.java
index fd09fbb..ea5c72e 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcutils/FileUtils.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/FileUtils.java
@@ -1,10 +1,8 @@
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;
@@ -15,39 +13,6 @@ import java.util.function.BiPredicate;
*
*/
public class FileUtils {
- private static final class FunctionalFileVisitor
- extends SimpleFileVisitor<Path> {
- private BiPredicate<Path, BasicFileAttributes> traversalPredicate;
- private BiPredicate<Path, BasicFileAttributes> traversalAction;
-
- public FunctionalFileVisitor(
- BiPredicate<Path, BasicFileAttributes> traversalPredicate,
- BiPredicate<Path, BasicFileAttributes> 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
*
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/FunctionalFileVisitor.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/FunctionalFileVisitor.java
new file mode 100644
index 0000000..6d3336a
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/FunctionalFileVisitor.java
@@ -0,0 +1,41 @@
+package bjc.utils.funcutils;
+
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.function.BiPredicate;
+
+final class FunctionalFileVisitor
+ extends SimpleFileVisitor<Path> {
+ private BiPredicate<Path, BasicFileAttributes> traversalPredicate;
+ private BiPredicate<Path, BasicFileAttributes> traversalAction;
+
+ public FunctionalFileVisitor(
+ BiPredicate<Path, BasicFileAttributes> traversalPredicate,
+ BiPredicate<Path, BasicFileAttributes> 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;
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/GroupPartIteration.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/GroupPartIteration.java
new file mode 100644
index 0000000..3837858
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/GroupPartIteration.java
@@ -0,0 +1,64 @@
+package bjc.utils.funcutils;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import bjc.utils.data.IHolder;
+import bjc.utils.funcdata.FunctionalList;
+import bjc.utils.funcdata.IFunctionalList;
+
+/**
+ * Implements a single group partitioning pass on a list
+ *
+ * @author ben
+ *
+ * @param <E>
+ * The type of element in the list being partitioned
+ */
+final class GroupPartIteration<E>
+ implements Consumer<E> {
+ private IFunctionalList<IFunctionalList<E>> returnedList;
+ private IHolder<IFunctionalList<E>> currentPartition;
+ private IFunctionalList<E> rejectedItems;
+ private IHolder<Integer> numberInCurrentPartition;
+ private int numberPerPartition;
+ private Function<E, Integer> elementCounter;
+
+ public GroupPartIteration(
+ IFunctionalList<IFunctionalList<E>> returned,
+ IHolder<IFunctionalList<E>> currPart,
+ IFunctionalList<E> rejects, IHolder<Integer> numInCurrPart,
+ int nPerPart, Function<E, Integer> eleCount) {
+ this.returnedList = returned;
+ this.currentPartition = currPart;
+ this.rejectedItems = rejects;
+ this.numberInCurrentPartition = numInCurrPart;
+ this.numberPerPartition = nPerPart;
+ this.elementCounter = eleCount;
+ }
+
+ @Override
+ public void accept(E value) {
+ if (numberInCurrentPartition
+ .unwrap((number) -> number >= numberPerPartition)) {
+ returnedList.add(
+ currentPartition.unwrap((partition) -> partition));
+
+ currentPartition
+ .transform((partition) -> new FunctionalList<>());
+ numberInCurrentPartition.transform((number) -> 0);
+ } else {
+ int currentElementCount = elementCounter.apply(value);
+
+ if (numberInCurrentPartition.unwrap((number) -> (number
+ + currentElementCount) >= numberPerPartition)) {
+ rejectedItems.add(value);
+ } else {
+ currentPartition
+ .unwrap((partition) -> partition.add(value));
+ numberInCurrentPartition.transform(
+ (number) -> number + currentElementCount);
+ }
+ }
+ }
+} \ No newline at end of file
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 977186a..95873e9 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java
@@ -2,13 +2,11 @@ package bjc.utils.funcutils;
import java.util.ArrayList;
import java.util.Deque;
-import java.util.function.BiFunction;
-import java.util.function.Consumer;
import java.util.function.Function;
-import bjc.utils.data.experimental.IHolder;
-import bjc.utils.data.experimental.IPair;
-import bjc.utils.data.experimental.Identity;
+import bjc.utils.data.IHolder;
+import bjc.utils.data.IPair;
+import bjc.utils.data.Identity;
import bjc.utils.funcdata.FunctionalList;
import bjc.utils.funcdata.IFunctionalList;
@@ -22,146 +20,6 @@ import bjc.utils.funcdata.IFunctionalList;
public class ListUtils {
private static final int MAX_NTRIESPART = 50;
- private static final class TokenDeaffixer implements
- BiFunction<String, String, IFunctionalList<String>> {
- private String token;
-
- public TokenDeaffixer(String tok) {
- token = tok;
- }
-
- @Override
- public IFunctionalList<String> apply(String operatorName,
- String operatorRegex) {
- if (operatorName == null) {
- throw new NullPointerException(
- "Operator name must not be null");
- } else if (operatorRegex == null) {
- throw new NullPointerException(
- "Operator regex must not be null");
- }
-
- if (StringUtils.containsOnly(token, operatorRegex)) {
- return new FunctionalList<>(token);
- } else if (token.startsWith(operatorName)) {
- return new FunctionalList<>(operatorName,
- token.split(operatorRegex)[1]);
- } else if (token.endsWith(operatorName)) {
- return new FunctionalList<>(token.split(operatorRegex)[0],
- operatorName);
- } else {
- return new FunctionalList<>(token);
- }
- }
- }
-
- private static final class TokenSplitter implements
- BiFunction<String, String, IFunctionalList<String>> {
- private String tokenToSplit;
-
- public TokenSplitter(String tok) {
- this.tokenToSplit = tok;
- }
-
- @Override
- public IFunctionalList<String> apply(String operatorName,
- String operatorRegex) {
- if (operatorName == null) {
- throw new NullPointerException(
- "Operator name must not be null");
- } else if (operatorRegex == null) {
- throw new NullPointerException(
- "Operator regex must not be null");
- }
-
- if (tokenToSplit.contains(operatorName)) {
- if (StringUtils.containsOnly(tokenToSplit,
- operatorRegex)) {
- return new FunctionalList<>(tokenToSplit);
- }
-
- IFunctionalList<String> splitTokens = new FunctionalList<>(
- tokenToSplit.split(operatorRegex));
-
- IFunctionalList<String> result = new FunctionalList<>();
-
- int tokenExpansionSize = splitTokens.getSize();
-
- splitTokens.forEachIndexed((tokenIndex, token) -> {
-
- if (tokenIndex != tokenExpansionSize
- && tokenIndex != 0) {
- result.add(operatorName);
- result.add(token);
- } else {
- result.add(token);
- }
- });
-
- return result;
- }
-
- return new FunctionalList<>(tokenToSplit);
- }
- }
-
- /**
- * Implements a single group partitioning pass on a list
- *
- * @author ben
- *
- * @param <E>
- * The type of element in the list being partitioned
- */
- private static final class GroupPartIteration<E>
- implements Consumer<E> {
- private IFunctionalList<IFunctionalList<E>> returnedList;
- private IHolder<IFunctionalList<E>> currentPartition;
- private IFunctionalList<E> rejectedItems;
- private IHolder<Integer> numberInCurrentPartition;
- private int numberPerPartition;
- private Function<E, Integer> elementCounter;
-
- public GroupPartIteration(
- IFunctionalList<IFunctionalList<E>> returned,
- IHolder<IFunctionalList<E>> currPart,
- IFunctionalList<E> rejects,
- IHolder<Integer> numInCurrPart, int nPerPart,
- Function<E, Integer> eleCount) {
- this.returnedList = returned;
- this.currentPartition = currPart;
- this.rejectedItems = rejects;
- this.numberInCurrentPartition = numInCurrPart;
- this.numberPerPartition = nPerPart;
- this.elementCounter = eleCount;
- }
-
- @Override
- public void accept(E value) {
- if (numberInCurrentPartition
- .unwrap((number) -> number >= numberPerPartition)) {
- returnedList.add(
- currentPartition.unwrap((partition) -> partition));
-
- currentPartition
- .transform((partition) -> new FunctionalList<>());
- numberInCurrentPartition.transform((number) -> 0);
- } else {
- int currentElementCount = elementCounter.apply(value);
-
- if (numberInCurrentPartition.unwrap((number) -> (number
- + currentElementCount) >= numberPerPartition)) {
- rejectedItems.add(value);
- } else {
- currentPartition
- .unwrap((partition) -> partition.add(value));
- numberInCurrentPartition.transform(
- (number) -> number + currentElementCount);
- }
- }
- }
- }
-
/**
* Partition a list into a list of lists, where each element can count
* for more than one element in a partition
@@ -195,13 +53,14 @@ public class ListUtils {
/*
* List that holds our results
*/
- IFunctionalList<IFunctionalList<E>> returnedList = new FunctionalList<>();
+ IFunctionalList<IFunctionalList<E>> returnedList =
+ new FunctionalList<>();
/*
* List that holds current partition
*/
- IHolder<IFunctionalList<E>> currentPartition = new Identity<>(
- new FunctionalList<>());
+ IHolder<IFunctionalList<E>> currentPartition =
+ new Identity<>(new FunctionalList<>());
/*
* List that holds elements rejected during current pass
*/
@@ -215,8 +74,10 @@ public class ListUtils {
/*
* Run up to a certain number of passes
*/
- for (int numberOfIterations = 0; numberOfIterations < MAX_NTRIESPART
- && !rejectedElements.isEmpty(); numberOfIterations++) {
+ for (int numberOfIterations =
+ 0; numberOfIterations < MAX_NTRIESPART
+ && !rejectedElements
+ .isEmpty(); numberOfIterations++) {
input.forEach(new GroupPartIteration<>(returnedList,
currentPartition, rejectedElements,
numberInCurrentPartition, numberPerPartition,
@@ -264,8 +125,8 @@ public class ListUtils {
"Set of operators must not be null");
}
- IHolder<IFunctionalList<String>> returnedList = new Identity<>(
- input);
+ IHolder<IFunctionalList<String>> returnedList =
+ new Identity<>(input);
operators.forEach((operator) -> returnedList
.transform((oldReturn) -> oldReturn.flatMap((token) -> {
@@ -295,8 +156,8 @@ public class ListUtils {
"Set of operators must not be null");
}
- IHolder<IFunctionalList<String>> returnedList = new Identity<>(
- input);
+ IHolder<IFunctionalList<String>> returnedList =
+ new Identity<>(input);
operators.forEach((operator) -> returnedList
.transform((oldReturn) -> oldReturn.flatMap((token) -> {
@@ -372,8 +233,8 @@ public class ListUtils {
public static <E> IFunctionalList<E> drawWithReplacement(
IFunctionalList<E> list, int numberOfItems,
Function<Integer, Integer> rng) {
- IFunctionalList<E> selectedItems = new FunctionalList<>(
- new ArrayList<>(numberOfItems));
+ IFunctionalList<E> selectedItems =
+ new FunctionalList<>(new ArrayList<>(numberOfItems));
for (int i = 0; i < numberOfItems; i++) {
selectedItems.add(list.randItem(rng));
@@ -401,8 +262,8 @@ public class ListUtils {
public static <E> IFunctionalList<E> drawWithoutReplacement(
IFunctionalList<E> list, int numberOfItems,
Function<Integer, Integer> rng) {
- IFunctionalList<E> selectedItems = new FunctionalList<>(
- new ArrayList<>(numberOfItems));
+ IFunctionalList<E> selectedItems =
+ new FunctionalList<>(new ArrayList<>(numberOfItems));
int totalItems = list.getSize();
@@ -420,4 +281,25 @@ public class ListUtils {
return selectedItems;
}
+
+ /**
+ * Merge the contents of a bunch of lists together into a single list
+ *
+ * @param <E>
+ * 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
+ */
+ @SafeVarargs
+ public static <E> IFunctionalList<E>
+ mergeLists(IFunctionalList<E>... lists) {
+ IFunctionalList<E> returnedList = new FunctionalList<>();
+
+ for (IFunctionalList<E> list : lists) {
+ list.forEach(returnedList::add);
+ }
+
+ return returnedList;
+ }
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java
index ac36d15..c58a42b 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java
@@ -57,4 +57,18 @@ public class StringUtils {
&& !expression.equalsIgnoreCase(operator)
&& !expression.startsWith(operator);
}
+
+ /**
+ * Indent the string being built in a StringBuilder n levels
+ *
+ * @param builder
+ * The builder to indent in
+ * @param levels
+ * The number of levels to indent
+ */
+ public static void indentNLevels(StringBuilder builder, int levels) {
+ for (int i = 0; i < levels; i++) {
+ builder.append("\t");
+ }
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenDeaffixer.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenDeaffixer.java
new file mode 100644
index 0000000..1cf5d44
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenDeaffixer.java
@@ -0,0 +1,39 @@
+package bjc.utils.funcutils;
+
+import java.util.function.BiFunction;
+
+import bjc.utils.funcdata.FunctionalList;
+import bjc.utils.funcdata.IFunctionalList;
+
+final class TokenDeaffixer implements
+ BiFunction<String, String, IFunctionalList<String>> {
+ private String token;
+
+ public TokenDeaffixer(String tok) {
+ token = tok;
+ }
+
+ @Override
+ public IFunctionalList<String> apply(String operatorName,
+ String operatorRegex) {
+ if (operatorName == null) {
+ throw new NullPointerException(
+ "Operator name must not be null");
+ } else if (operatorRegex == null) {
+ throw new NullPointerException(
+ "Operator regex must not be null");
+ }
+
+ if (StringUtils.containsOnly(token, operatorRegex)) {
+ return new FunctionalList<>(token);
+ } else if (token.startsWith(operatorName)) {
+ return new FunctionalList<>(operatorName,
+ token.split(operatorRegex)[1]);
+ } else if (token.endsWith(operatorName)) {
+ return new FunctionalList<>(token.split(operatorRegex)[0],
+ operatorName);
+ } else {
+ return new FunctionalList<>(token);
+ }
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenSplitter.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenSplitter.java
new file mode 100644
index 0000000..0da9f7d
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenSplitter.java
@@ -0,0 +1,56 @@
+package bjc.utils.funcutils;
+
+import java.util.function.BiFunction;
+
+import bjc.utils.funcdata.FunctionalList;
+import bjc.utils.funcdata.IFunctionalList;
+
+final class TokenSplitter implements
+ BiFunction<String, String, IFunctionalList<String>> {
+ private String tokenToSplit;
+
+ public TokenSplitter(String tok) {
+ this.tokenToSplit = tok;
+ }
+
+ @Override
+ public IFunctionalList<String> apply(String operatorName,
+ String operatorRegex) {
+ if (operatorName == null) {
+ throw new NullPointerException(
+ "Operator name must not be null");
+ } else if (operatorRegex == null) {
+ throw new NullPointerException(
+ "Operator regex must not be null");
+ }
+
+ if (tokenToSplit.contains(operatorName)) {
+ if (StringUtils.containsOnly(tokenToSplit,
+ operatorRegex)) {
+ return new FunctionalList<>(tokenToSplit);
+ }
+
+ IFunctionalList<String> splitTokens = new FunctionalList<>(
+ tokenToSplit.split(operatorRegex));
+
+ IFunctionalList<String> result = new FunctionalList<>();
+
+ int tokenExpansionSize = splitTokens.getSize();
+
+ splitTokens.forEachIndexed((tokenIndex, token) -> {
+
+ if (tokenIndex != tokenExpansionSize
+ && tokenIndex != 0) {
+ result.add(operatorName);
+ result.add(token);
+ } else {
+ result.add(token);
+ }
+ });
+
+ return result;
+ }
+
+ return new FunctionalList<>(tokenToSplit);
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/gen/RandomGrammar.java b/BJC-Utils2/src/main/java/bjc/utils/gen/RandomGrammar.java
index 349d9fa..963fb32 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/gen/RandomGrammar.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/gen/RandomGrammar.java
@@ -12,7 +12,6 @@ import bjc.utils.funcdata.IFunctionalList;
* The type of grammar elements to use.
*/
public class RandomGrammar<E> extends WeightedGrammar<E> {
-
/**
* Create a new random grammar.
*/
diff --git a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java
index 3eae47e..8d31576 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java
@@ -3,8 +3,8 @@ package bjc.utils.gen;
import java.util.Random;
import java.util.function.Function;
-import bjc.utils.data.experimental.IPair;
-import bjc.utils.data.experimental.Pair;
+import bjc.utils.data.IPair;
+import bjc.utils.data.Pair;
import bjc.utils.funcdata.FunctionalList;
import bjc.utils.funcdata.FunctionalMap;
import bjc.utils.funcdata.IFunctionalList;
diff --git a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedRandom.java b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedRandom.java
index f10ee26..43d9928 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedRandom.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedRandom.java
@@ -2,9 +2,9 @@ package bjc.utils.gen;
import java.util.Random;
-import bjc.utils.data.experimental.IHolder;
-import bjc.utils.data.experimental.IPair;
-import bjc.utils.data.experimental.Identity;
+import bjc.utils.data.IHolder;
+import bjc.utils.data.IPair;
+import bjc.utils.data.Identity;
import bjc.utils.funcdata.FunctionalList;
import bjc.utils.funcdata.IFunctionalList;
diff --git a/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java b/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java
index 56b4653..7b240b8 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java
@@ -7,12 +7,13 @@ import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.stream.IntStream;
-import bjc.utils.data.experimental.IHolder;
-import bjc.utils.data.experimental.Identity;
+import bjc.utils.data.IHolder;
+import bjc.utils.data.Identity;
import bjc.utils.funcdata.FunctionalList;
import bjc.utils.funcdata.FunctionalMap;
import bjc.utils.funcdata.IFunctionalList;
import bjc.utils.funcdata.IFunctionalMap;
+import bjc.utils.funcutils.FuncUtils;
/**
* An adjacency map representing a graph
@@ -67,54 +68,54 @@ public class AdjacencyMap<T> {
IFunctionalList<Integer> vertices = new FunctionalList<>();
- IntStream.range(0, numVertices)
- .forEach(element -> vertices.add(element));
+ FuncUtils.doTimes(numVertices,
+ (vertexNo) -> vertices.add(vertexNo));
adjacencyMap = new AdjacencyMap<>(vertices);
IHolder<Integer> row = new Identity<>(0);
inputSource.forEachRemaining((strang) -> {
- String[] parts = strang.split(" ");
+ readRow(adjacencyMap, numVertices, row, strang);
+ });
+ }
- if (parts.length != numVertices) {
- throw new InputMismatchException(
- "Must specify a weight for all " + numVertices
- + " vertices");
- }
+ return adjacencyMap;
+ }
- int column = 0;
+ private static void readRow(AdjacencyMap<Integer> adjacencyMap,
+ int numVertices, IHolder<Integer> row, String strang) {
+ String[] parts = strang.split(" ");
- for (String part : parts) {
- int columnWeight;
+ if (parts.length != numVertices) {
+ throw new InputMismatchException(
+ "Must specify a weight for all " + numVertices
+ + " vertices");
+ }
- try {
- columnWeight = Integer.parseInt(part);
- } catch (NumberFormatException nfex) {
- InputMismatchException imex =
- new InputMismatchException("" + part
- + " is not a valid weight.");
+ int column = 0;
- imex.initCause(nfex);
+ for (String part : parts) {
+ int columnWeight;
- throw imex;
- }
+ try {
+ columnWeight = Integer.parseInt(part);
+ } catch (NumberFormatException nfex) {
+ InputMismatchException imex = new InputMismatchException(
+ "" + part + " is not a valid weight.");
- adjacencyMap.setWeight(row.unwrap(number -> number),
- column, columnWeight);
+ imex.initCause(nfex);
- column++;
- }
+ throw imex;
+ }
- row.transform((number) -> {
- int newNumber = number + 1;
+ adjacencyMap.setWeight(row.getValue(), column,
+ columnWeight);
- return newNumber;
- });
- });
+ column++;
}
- return adjacencyMap;
+ row.transform((rowNumber) -> rowNumber + 1);
}
/**
@@ -137,8 +138,9 @@ public class AdjacencyMap<T> {
vertices.forEach(vertex -> {
IFunctionalMap<T, Integer> vertexRow = new FunctionalMap<>();
- vertices.forEach(
- targetVertex -> vertexRow.put(targetVertex, 0));
+ vertices.forEach(targetVertex -> {
+ vertexRow.put(targetVertex, 0);
+ });
adjacencyMap.put(vertex, vertexRow);
});
@@ -157,12 +159,12 @@ public class AdjacencyMap<T> {
int inverseValue = adjacencyMap.get(targetKey).get(key);
if (targetValue != inverseValue) {
- result.transform((bool) -> false);
+ result.replace(false);
}
});
});
- return result.unwrap(bool -> bool);
+ return result.getValue();
}
/**
diff --git a/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java b/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java
index a72304d..d08c3f9 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java
@@ -10,8 +10,8 @@ import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiPredicate;
-import bjc.utils.data.experimental.IHolder;
-import bjc.utils.data.experimental.Identity;
+import bjc.utils.data.IHolder;
+import bjc.utils.data.Identity;
import bjc.utils.funcdata.FunctionalMap;
import bjc.utils.funcdata.IFunctionalList;
import bjc.utils.funcdata.IFunctionalMap;
@@ -25,7 +25,6 @@ import bjc.utils.funcdata.IFunctionalMap;
* The label for vertices
*/
public class Graph<T> {
-
/**
* The backing representation of the graph
*/
@@ -157,20 +156,20 @@ public class Graph<T> {
// Start at the initial vertex and visit it
IHolder<T> sourceVertex = new Identity<>(getInitial());
- visitedVertexes.add(sourceVertex.unwrap(vertex -> vertex));
+ visitedVertexes.add(sourceVertex.getValue());
// Make sure we visit all the nodes
while (visitedVertexes.size() != getVertexCount()) {
// Grab all edges adjacent to the provided edge
- forAllEdgesMatchingAt(sourceVertex.unwrap(vertex -> vertex),
- (targetVertex,
- vertexWeight) -> !visitedVertexes
- .contains(targetVertex),
- (targetVertex,
- vertexWeight) -> availableEdges.add(new Edge<>(
- sourceVertex.unwrap(vertex -> vertex),
- targetVertex, vertexWeight)));
+ forAllEdgesMatchingAt(sourceVertex.getValue(),
+ (targetVertex, vertexWeight) -> {
+ return !visitedVertexes.contains(targetVertex);
+ }, (targetVertex, vertexWeight) -> {
+ availableEdges.add(new Edge<>(
+ sourceVertex.unwrap(vertex -> vertex),
+ targetVertex, vertexWeight));
+ });
// Get the edge with the minimum distance
IHolder<Edge<T>> minimumEdge =
@@ -178,20 +177,19 @@ public class Graph<T> {
// Only consider edges where we haven't visited the target of
// the edge
- while (visitedVertexes.contains(
- minimumEdge.unwrap(vertex -> vertex.getTarget()))) {
+ while (visitedVertexes.contains(minimumEdge.getValue())) {
minimumEdge.transform((edge) -> availableEdges.poll());
}
// Add it to our MST
- minimumEdges.add(minimumEdge.unwrap(edge -> edge));
+ minimumEdges.add(minimumEdge.getValue());
// Advance to the next node
sourceVertex.transform((vertex) -> minimumEdge
.unwrap(edge -> edge.getTarget()));
// Visit this node
- visitedVertexes.add(sourceVertex.unwrap(vertex -> vertex));
+ visitedVertexes.add(sourceVertex.getValue());
}
return minimumEdges;
@@ -281,8 +279,10 @@ public class Graph<T> {
public static <E> Graph<E> fromEdgeList(List<Edge<E>> edges) {
Graph<E> g = new Graph<>();
- edges.forEach(edge -> g.addEdge(edge.getSource(), edge.getTarget(),
- edge.getDistance(), true));
+ edges.forEach(edge -> {
+ g.addEdge(edge.getSource(), edge.getTarget(),
+ edge.getDistance(), true);
+ });
return g;
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/ListParameterPanel.java b/BJC-Utils2/src/main/java/bjc/utils/gui/ListParameterPanel.java
index 26a5a78..956c535 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/gui/ListParameterPanel.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/gui/ListParameterPanel.java
@@ -89,26 +89,33 @@ public class ListParameterPanel<E> extends JPanel {
if (addAction != null) {
addParam = new JButton("Add...");
- addParam.addActionListener(
- (event) -> ((DefaultListModel<E>) list.getModel())
- .addElement(addAction.get()));
+ addParam.addActionListener((event) -> {
+ DefaultListModel<E> model =
+ (DefaultListModel<E>) list.getModel();
+
+ model.addElement(addAction.get());
+ });
}
JButton editParam = null;
if (editAction != null) {
editParam = new JButton("Edit...");
- editParam.addActionListener(
- (event) -> editAction.accept(list.getSelectedValue()));
+ editParam.addActionListener((event) -> {
+ editAction.accept(list.getSelectedValue());
+ });
}
JButton removeParam = null;
if (removeAction != null) {
removeParam = new JButton("Remove...");
- removeParam.addActionListener((event) -> removeAction
- .accept(((DefaultListModel<E>) list.getModel())
- .remove(list.getSelectedIndex())));
+ removeParam.addActionListener((event) -> {
+ DefaultListModel<E> model =
+ (DefaultListModel<E>) list.getModel();
+
+ removeAction.accept(model.remove(list.getSelectedIndex()));
+ });
}
if (addAction != null) {
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java
index 9bb20a5..c31066c 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java
@@ -8,8 +8,8 @@ import java.util.Scanner;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
-import bjc.utils.data.experimental.IPair;
-import bjc.utils.data.experimental.Pair;
+import bjc.utils.data.IPair;
+import bjc.utils.data.Pair;
import bjc.utils.exceptions.UnknownPragmaException;
import bjc.utils.funcdata.FunctionalStringTokenizer;
@@ -100,58 +100,13 @@ public class RuleBasedConfigReader<E> {
// It's a comment
continue;
} else if (line.equals("")) {
- if (ruleOpen == false) {
- // Ignore blank line without an open rule
- } else {
- if (endRule == null) {
- // Nothing happens on rule end
- ruleOpen = false;
- } else {
- endRule.accept(state);
- }
-
- ruleOpen = false;
- }
+ ruleOpen = endRule(state, ruleOpen);
+
continue;
} else if (line.startsWith("\t")) {
- if (ruleOpen == false) {
- throw new InputMismatchException(
- "Can't continue rule with no rule currently open");
- }
-
- if (continueRule == null) {
- throw new InputMismatchException(
- "Attempted to continue rule with rule continuation disabled."
- + " Check for extraneous tabs");
- }
-
- continueRule.accept(new FunctionalStringTokenizer(
- line.substring(1), " "), state);
+ continueRule(state, ruleOpen, line);
} else {
- FunctionalStringTokenizer tokenizer =
- new FunctionalStringTokenizer(line, " ");
-
- String nextToken = tokenizer.nextToken();
-
- if (nextToken.equals("pragma")) {
- String token = tokenizer.nextToken();
-
- pragmas.getOrDefault(token, (tokenzer, stat) -> {
- throw new UnknownPragmaException(
- "Unknown pragma " + token);
- }).accept(tokenizer, state);
- } else {
- if (ruleOpen == true) {
- throw new InputMismatchException(
- "Attempted to open a"
- + " rule with a rule already open. Make sure rules are"
- + " seperated by blank lines");
- }
-
- startRule.accept(tokenizer,
- new Pair<>(nextToken, state));
- ruleOpen = true;
- }
+ ruleOpen = startRule(state, ruleOpen, line);
}
}
}
@@ -159,6 +114,65 @@ public class RuleBasedConfigReader<E> {
return state;
}
+ private boolean startRule(E state, boolean ruleOpen, String line) {
+ FunctionalStringTokenizer tokenizer =
+ new FunctionalStringTokenizer(line, " ");
+
+ String nextToken = tokenizer.nextToken();
+
+ if (nextToken.equals("pragma")) {
+ String token = tokenizer.nextToken();
+
+ pragmas.getOrDefault(token, (tokenzer, stat) -> {
+ throw new UnknownPragmaException(
+ "Unknown pragma " + token);
+ }).accept(tokenizer, state);
+ } else {
+ if (ruleOpen == true) {
+ throw new InputMismatchException("Attempted to open a"
+ + " rule with a rule already open. Make sure rules are"
+ + " seperated by blank lines");
+ }
+
+ startRule.accept(tokenizer, new Pair<>(nextToken, state));
+ ruleOpen = true;
+ }
+ return ruleOpen;
+ }
+
+ private void continueRule(E state, boolean ruleOpen, String line) {
+ if (ruleOpen == false) {
+ throw new InputMismatchException(
+ "Can't continue rule with no rule currently open");
+ }
+
+ if (continueRule == null) {
+ throw new InputMismatchException(
+ "Attempted to continue rule with rule continuation disabled."
+ + " Check for extraneous tabs");
+ }
+
+ continueRule.accept(
+ new FunctionalStringTokenizer(line.substring(1), " "),
+ state);
+ }
+
+ private boolean endRule(E state, boolean ruleOpen) {
+ if (ruleOpen == false) {
+ // Ignore blank line without an open rule
+ } else {
+ if (endRule == null) {
+ // Nothing happens on rule end
+ ruleOpen = false;
+ } else {
+ endRule.accept(state);
+ }
+
+ ruleOpen = false;
+ }
+ return ruleOpen;
+ }
+
/**
* Set the action to execute when continuing a rule
*
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java
index a60cb01..9c7618b 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java
@@ -161,10 +161,15 @@ public class ShuntingYard<E> {
operators.put(operatorToken, precedence);
}
- private boolean isHigherPrec(String operator, String rightOperator) {
- return (operators.containsKey(rightOperator) && operators
- .get(rightOperator).getPrecedence() >= operators
- .get(operator).getPrecedence());
+ private boolean isHigherPrec(String leftOperator,
+ String rightOperator) {
+ boolean operatorExists = operators.containsKey(rightOperator);
+
+ boolean hasHigherPrecedence =
+ operators.get(rightOperator).getPrecedence() >= operators
+ .get(leftOperator).getPrecedence();
+
+ return (operatorExists && hasHigherPrecedence);
}
/**
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenTransformer.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenTransformer.java
new file mode 100644
index 0000000..4db5e76
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenTransformer.java
@@ -0,0 +1,94 @@
+package bjc.utils.parserutils;
+
+import java.util.Deque;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
+
+import bjc.utils.data.IHolder;
+import bjc.utils.data.IPair;
+import bjc.utils.data.Pair;
+import bjc.utils.funcdata.ITree;
+import bjc.utils.funcdata.Tree;
+
+final class TokenTransformer<T> implements Consumer<T> {
+ private final class OperatorHandler
+ implements UnaryOperator<IPair<Deque<ITree<T>>, ITree<T>>> {
+ private T element;
+
+ public OperatorHandler(T element) {
+ this.element = element;
+ }
+
+ @Override
+ public IPair<Deque<ITree<T>>, ITree<T>>
+ apply(IPair<Deque<ITree<T>>, ITree<T>> pair) {
+ return pair.bind((queuedASTs, currentAST) -> {
+ return handleOperator(queuedASTs);
+ });
+ }
+
+ private IPair<Deque<ITree<T>>, ITree<T>>
+ handleOperator(Deque<ITree<T>> queuedASTs) {
+ ITree<T> newAST;
+
+ if (isSpecialOperator.test(element)) {
+ newAST = handleSpecialOperator.apply(queuedASTs);
+ } else {
+ if (queuedASTs.size() < 2) {
+ throw new IllegalStateException(
+ "Attempted to parse binary operator without enough operands.\n"
+ + "Problem operator is " + element
+ + "\nPossible operand is: \n\t"
+ + queuedASTs.peek());
+ }
+
+ ITree<T> rightAST = queuedASTs.pop();
+ ITree<T> leftAST = queuedASTs.pop();
+
+ newAST = new Tree<>(element, leftAST, rightAST);
+ }
+
+ queuedASTs.push(newAST);
+
+ return new Pair<>(queuedASTs, newAST);
+ }
+ }
+
+ private IHolder<IPair<Deque<ITree<T>>, ITree<T>>> initialState;
+ private Predicate<T> operatorPredicate;
+ private Predicate<T> isSpecialOperator;
+ private Function<Deque<ITree<T>>, ITree<T>> handleSpecialOperator;
+
+ public TokenTransformer(
+ IHolder<IPair<Deque<ITree<T>>, ITree<T>>> initialState,
+ Predicate<T> operatorPredicate, Predicate<T> isSpecialOperator,
+ Function<Deque<ITree<T>>, ITree<T>> handleSpecialOperator) {
+ this.initialState = initialState;
+ this.operatorPredicate = operatorPredicate;
+ this.isSpecialOperator = isSpecialOperator;
+ this.handleSpecialOperator = handleSpecialOperator;
+ }
+
+ @Override
+ public void accept(T element) {
+ if (operatorPredicate.test(element)) {
+ initialState.transform(new OperatorHandler(element));
+ } else {
+ ITree<T> newAST = new Tree<>(element);
+
+ initialState.doWith((pair) -> {
+ pair.doWith((queue, currentAST) -> {
+ queue.push(newAST);
+ });
+ });
+
+ initialState.transform((pair) -> {
+ return pair.bind((queue, currentAST) -> {
+ return new Pair<>(queue, newAST);
+ });
+ });
+ }
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java
index 52299bb..efd0394 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java
@@ -2,18 +2,15 @@ package bjc.utils.parserutils;
import java.util.Deque;
import java.util.LinkedList;
-import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
-import java.util.function.UnaryOperator;
-import bjc.utils.data.experimental.IHolder;
-import bjc.utils.data.experimental.IPair;
-import bjc.utils.data.experimental.Identity;
-import bjc.utils.data.experimental.Pair;
+import bjc.utils.data.IHolder;
+import bjc.utils.data.IPair;
+import bjc.utils.data.Identity;
+import bjc.utils.data.Pair;
import bjc.utils.funcdata.IFunctionalList;
import bjc.utils.funcdata.ITree;
-import bjc.utils.funcdata.Tree;
/**
* Creates a parse tree from a postfix expression
@@ -22,88 +19,6 @@ import bjc.utils.funcdata.Tree;
*
*/
public class TreeConstructor {
- private static final class TokenTransformer<T> implements Consumer<T> {
- private final class OperatorHandler implements
- UnaryOperator<IPair<Deque<ITree<T>>, ITree<T>>> {
- private T element;
-
- public OperatorHandler(T element) {
- this.element = element;
- }
-
- @Override
- public IPair<Deque<ITree<T>>, ITree<T>> apply(
- IPair<Deque<ITree<T>>, ITree<T>> pair) {
- return pair.bind((queuedASTs, currentAST) -> {
- return handleOperator(queuedASTs);
- });
- }
-
- private IPair<Deque<ITree<T>>, ITree<T>> handleOperator(
- Deque<ITree<T>> queuedASTs) {
- ITree<T> newAST;
-
- if (isSpecialOperator.test(element)) {
- newAST = handleSpecialOperator.apply(queuedASTs);
- } else {
- if (queuedASTs.size() < 2) {
- throw new IllegalStateException(
- "Attempted to parse binary operator without enough operands.\n"
- + "Problem operator is " + element
- + "\nPossible operand is: \n\t"
- + queuedASTs.peek());
- }
-
- ITree<T> rightAST = queuedASTs.pop();
- ITree<T> leftAST = queuedASTs.pop();
-
- newAST = new Tree<>(element, leftAST, rightAST);
- }
-
- queuedASTs.push(newAST);
-
- return new Pair<>(queuedASTs, newAST);
- }
- }
-
- private IHolder<IPair<Deque<ITree<T>>, ITree<T>>> initialState;
- private Predicate<T> operatorPredicate;
- private Predicate<T> isSpecialOperator;
- private Function<Deque<ITree<T>>, ITree<T>> handleSpecialOperator;
-
- public TokenTransformer(
- IHolder<IPair<Deque<ITree<T>>, ITree<T>>> initialState,
- Predicate<T> operatorPredicate,
- Predicate<T> isSpecialOperator,
- Function<Deque<ITree<T>>, ITree<T>> handleSpecialOperator) {
- this.initialState = initialState;
- this.operatorPredicate = operatorPredicate;
- this.isSpecialOperator = isSpecialOperator;
- this.handleSpecialOperator = handleSpecialOperator;
- }
-
- @Override
- public void accept(T element) {
- if (operatorPredicate.test(element)) {
- initialState.transform(new OperatorHandler(element));
- } else {
- ITree<T> newAST = new Tree<>(element);
-
- initialState.doWith((pair) -> {
- pair.doWith((queue, currentAST) -> {
- queue.push(newAST);
- });
- });
-
- initialState.transform((pair) -> {
- return pair.bind((queue, currentAST) -> {
- return new Pair<>(queue, newAST);
- });
- });
- }
- }
- }
-
/**
* Construct a tree from a list of tokens in postfix notation
*
@@ -161,15 +76,15 @@ public class TreeConstructor {
"Special operator determiner must not be null");
}
- IHolder<IPair<Deque<ITree<T>>, ITree<T>>> initialState = new Identity<>(
- new Pair<>(new LinkedList<>(), null));
+ IHolder<IPair<Deque<ITree<T>>, ITree<T>>> initialState =
+ new Identity<>(new Pair<>(new LinkedList<>(), null));
tokens.forEach(
new TokenTransformer<>(initialState, operatorPredicate,
isSpecialOperator, handleSpecialOperator));
return initialState.unwrap((pair) -> {
- return pair.merge((queue, currentAST) -> currentAST);
+ return pair.getRight();
});
}
}