From c8a00b789671d59589bcb5520c1e9d208bcc27f6 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Mon, 11 Apr 2016 21:54:44 -0400 Subject: Work on restructing data. --- .../java/bjc/utils/data/experimental/IHolder.java | 18 +- .../java/bjc/utils/data/experimental/IPair.java | 84 ++++++ .../java/bjc/utils/data/experimental/Identity.java | 82 +++--- .../java/bjc/utils/data/experimental/Lazy.java | 39 ++- .../java/bjc/utils/data/experimental/LazyPair.java | 317 +++++++++++++++++++++ .../java/bjc/utils/data/experimental/Pair.java | 63 ++++ 6 files changed, 548 insertions(+), 55 deletions(-) create mode 100644 BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/data/experimental/LazyPair.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/data/experimental/Pair.java (limited to 'BJC-Utils2/src/main/java/bjc/utils/data/experimental') diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java index 2767897..7d1d7a0 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java @@ -15,8 +15,11 @@ import java.util.function.UnaryOperator; public interface IHolder { /** * Bind a function across the value in this container - * @param The type of value in this container - * @param binder The function to bind to the value + * + * @param + * The type of value in this container + * @param binder + * The function to bind to the value * @return A holder from binding the value */ public IHolder bind( @@ -82,4 +85,15 @@ public interface IHolder { */ public UnwrappedType unwrap( Function unwrapper); + + /** + * Replace the held value with a new one + * + * @param newValue + * The value to hold instead + * @return The holder itself + */ + public default IHolder replace(ContainedType newValue) { + return transform((oldValue) -> newValue); + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java new file mode 100644 index 0000000..fb9648e --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java @@ -0,0 +1,84 @@ +package bjc.utils.data.experimental; + +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * Represents a pair of values + * + * @author ben + * @param + * The type of the left side of the pair + * @param + * The type of the right side of the pair + * + */ +public interface IPair { + /** + * Bind a function to the left value in this pair + * + * @param + * The type of the bound value + * @param leftBinder + * The function to use to bind + * @return A pair with the left type bound + */ + public IPair bindLeft( + Function> leftBinder); + + /** + * Bind a function to the right value in this pair + * + * @param + * The type of the bound value + * @param rightBinder + * The function to use to bind + * @return A pair with the right type bound + */ + public IPair bindRight( + Function> rightBinder); + + /** + * Bind a function across the values in this pair + * + * @param + * The type of the bound left + * @param + * The type of the bound right + * @param binder + * The function to bind with + * @return The bound pair + */ + public IPair bind( + BiFunction> binder); + + /** + * Merge the two values in this pair into a single value + * + * @param + * The type of the single value + * @param merger + * The function to use for merging + * @return The pair, merged into a single value + */ + public MergedType merge( + BiFunction merger); + + /** + * Get the value on the left side of the pair + * + * @return The value on the left side of the pair + */ + public default LeftType getLeft() { + return merge((leftValue, rightValue) -> leftValue); + } + + /** + * Get the value on the right side of the pair + * + * @return The value on the right side of the pair + */ + public default RightType getRight() { + return merge((leftValue, rightValue) -> rightValue); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java index 3cf0987..1780f2d 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java @@ -42,29 +42,32 @@ public class Identity implements IHolder { return binder.apply(heldValue); } + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ @Override - public IHolder map( - Function mapper) { - return new Identity<>(mapper.apply(heldValue)); - } - - @Override - public IHolder transform( - UnaryOperator transformer) { - heldValue = transformer.apply(heldValue); + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (obj == null) { + return false; + } else if (getClass() != obj.getClass()) { + return false; + } - return this; - } + Identity other = (Identity) obj; - @Override - public UnwrappedType unwrap( - Function unwrapper) { - return unwrapper.apply(heldValue); - } + if (heldValue == null) { + if (other.heldValue != null) { + return false; + } + } else if (!heldValue.equals(other.heldValue)) { + return false; + } - @Override - public String toString() { - return "holding[v=" + heldValue + "]"; + return true; } /* @@ -85,31 +88,28 @@ public class Identity implements IHolder { return result; } - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } else if (obj == null) { - return false; - } else if (getClass() != obj.getClass()) { - return false; - } + public IHolder map( + Function mapper) { + return new Identity<>(mapper.apply(heldValue)); + } - Identity other = (Identity) obj; + @Override + public String toString() { + return "holding[v=" + heldValue + "]"; + } - if (heldValue == null) { - if (other.heldValue != null) { - return false; - } - } else if (!heldValue.equals(other.heldValue)) { - return false; - } + @Override + public IHolder transform( + UnaryOperator transformer) { + heldValue = transformer.apply(heldValue); - return true; + return this; + } + + @Override + public UnwrappedType unwrap( + Function unwrapper) { + return unwrapper.apply(heldValue); } } \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java index e919fec..0d6fcef 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java @@ -26,8 +26,7 @@ public class Lazy implements IHolder { private boolean holderBound; - private IFunctionalList> actions = - new FunctionalList<>(); + private IFunctionalList> actions = new FunctionalList<>(); public BoundLazy(Supplier> supp, Function> binder) { @@ -38,8 +37,7 @@ public class Lazy implements IHolder { @Override public IHolder bind( Function> bindr) { - IFunctionalList> pendingActions = - new FunctionalList<>(); + IFunctionalList> pendingActions = new FunctionalList<>(); actions.forEach(pendingActions::add); @@ -62,8 +60,7 @@ public class Lazy implements IHolder { @Override public IHolder map( Function mapper) { - IFunctionalList> pendingActions = - new FunctionalList<>(); + IFunctionalList> pendingActions = new FunctionalList<>(); actions.forEach(pendingActions::add); @@ -101,12 +98,19 @@ public class Lazy implements IHolder { return boundHolder.unwrap(unwrapper); } + @Override + public String toString() { + if (holderBound) { + return boundHolder.toString(); + } + + return "(unmaterialized)"; + } } private Supplier valueSupplier; - private IFunctionalList> actions = - new FunctionalList<>(); + private IFunctionalList> actions = new FunctionalList<>(); private boolean valueMaterialized; @@ -146,8 +150,7 @@ public class Lazy implements IHolder { @Override public IHolder bind( Function> binder) { - IFunctionalList> pendingActions = - new FunctionalList<>(); + IFunctionalList> pendingActions = new FunctionalList<>(); actions.forEach(pendingActions::add); @@ -167,8 +170,7 @@ public class Lazy implements IHolder { @Override public IHolder map( Function mapper) { - IFunctionalList> pendingActions = - new FunctionalList<>(); + IFunctionalList> pendingActions = new FunctionalList<>(); actions.forEach(pendingActions::add); @@ -210,4 +212,17 @@ public class Lazy implements IHolder { return unwrapper.apply(heldValue); } + + @Override + public String toString() { + if (valueMaterialized) { + if (actions.isEmpty()) { + return "value[v='" + heldValue + "']"; + } + + return "value[v='" + heldValue + "'] (has pending transforms)"; + } + + return "(unmaterialized)"; + } } 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 new file mode 100644 index 0000000..04a4b61 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/LazyPair.java @@ -0,0 +1,317 @@ +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 + * The type on the left side of the pair + * @param + * The type on the right side of the pair + */ +public class LazyPair + implements IPair { + private static class HalfBoundLazyPair + implements IPair { + private Supplier oldSupplier; + + private Function> binder; + + private IPair boundPair; + private boolean pairBound; + + public HalfBoundLazyPair(Supplier oldSupp, + Function> bindr) { + oldSupplier = oldSupp; + binder = bindr; + } + + @Override + public IPair bindLeft( + Function> leftBinder) { + Supplier leftSupp = () -> { + IPair newPair = boundPair; + + if (!pairBound) { + newPair = binder.apply(oldSupplier.get()); + } + + return newPair.getLeft(); + }; + + return new HalfBoundLazyPair<>(leftSupp, leftBinder); + } + + @Override + public IPair bindRight( + Function> rightBinder) { + Supplier rightSupp = () -> { + IPair newPair = boundPair; + + if (!pairBound) { + newPair = binder.apply(oldSupplier.get()); + } + + return newPair.getRight(); + }; + + return new HalfBoundLazyPair<>(rightSupp, rightBinder); + } + + @Override + public IPair bind( + BiFunction> bindr) { + IHolder> newPair = new Identity<>( + boundPair); + IHolder newPairMade = new Identity<>(pairBound); + + Supplier leftSupp = () -> { + if (!newPairMade.getValue()) { + newPair.replace(binder.apply(oldSupplier.get())); + newPairMade.replace(true); + } + + return newPair.unwrap((pair) -> pair.getLeft()); + }; + + Supplier 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 merge( + BiFunction merger) { + if (!pairBound) { + boundPair = binder.apply(oldSupplier.get()); + + pairBound = true; + } + + return boundPair.merge(merger); + } + } + + private static class BoundLazyPair + implements IPair { + private Supplier leftSupplier; + private Supplier rightSupplier; + + private BiFunction> binder; + + private IPair boundPair; + + private boolean pairBound; + + public BoundLazyPair(Supplier leftSupp, + Supplier rightSupp, + BiFunction> bindr) { + leftSupplier = leftSupp; + rightSupplier = rightSupp; + binder = bindr; + } + + @Override + public IPair bindLeft( + Function> leftBinder) { + Supplier leftSupp = () -> { + IPair newPair = boundPair; + + if (!pairBound) { + newPair = binder.apply(leftSupplier.get(), + rightSupplier.get()); + } + + return newPair.getLeft(); + }; + + return new HalfBoundLazyPair<>(leftSupp, leftBinder); + } + + @Override + public IPair bindRight( + Function> rightBinder) { + Supplier rightSupp = () -> { + IPair newPair = boundPair; + + if (!pairBound) { + newPair = binder.apply(leftSupplier.get(), + rightSupplier.get()); + } + + return newPair.getRight(); + }; + + return new HalfBoundLazyPair<>(rightSupp, rightBinder); + } + + @Override + public IPair bind( + BiFunction> bindr) { + IHolder> newPair = new Identity<>( + boundPair); + IHolder 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 merge( + BiFunction merger) { + if (!pairBound) { + boundPair = binder.apply(leftSupplier.get(), + rightSupplier.get()); + + pairBound = true; + } + + return boundPair.merge(merger); + } + } + + private LeftType leftValue; + private RightType rightValue; + + private Supplier leftSupplier; + private Supplier 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 leftSupp, + Supplier rightSupp) { + leftSupplier = leftSupp; + rightSupplier = rightSupp; + + leftMaterialized = false; + rightMaterialized = false; + } + + @Override + public IPair bindLeft( + Function> leftBinder) { + Supplier leftSupp = () -> { + if (leftMaterialized) { + return leftValue; + } + + return leftSupplier.get(); + }; + + return new HalfBoundLazyPair<>(leftSupp, leftBinder); + } + + @Override + public IPair bindRight( + Function> rightBinder) { + Supplier rightSupp = () -> { + if (rightMaterialized) { + return rightValue; + } + + return rightSupplier.get(); + }; + + return new HalfBoundLazyPair<>(rightSupp, rightBinder); + } + + @Override + public IPair bind( + BiFunction> binder) { + return new BoundLazyPair<>(leftSupplier, rightSupplier, binder); + } + + @Override + public MergedType merge( + BiFunction 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/experimental/Pair.java new file mode 100644 index 0000000..87378d7 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Pair.java @@ -0,0 +1,63 @@ +package bjc.utils.data.experimental; + +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * A pair of values, with nothing special about them. + * + * @author ben + * + * @param + * The type of the left value + * @param + * The type of the right value + */ +public class Pair + implements IPair { + private LeftType leftValue; + private RightType rightValue; + + /** + * Create a new pair with both sides set to null + */ + public Pair() { + } + + /** + * Create a new pair with both sides set to the specified values + * + * @param left + * The value of the left side + * @param right + * The value of the right side + */ + public Pair(LeftType left, RightType right) { + leftValue = left; + rightValue = right; + } + + @Override + public IPair bindLeft( + Function> leftBinder) { + return leftBinder.apply(leftValue); + } + + @Override + public IPair bindRight( + Function> rightBinder) { + return rightBinder.apply(rightValue); + } + + @Override + public IPair bind( + BiFunction> binder) { + return binder.apply(leftValue, rightValue); + } + + @Override + public MergedType merge( + BiFunction merger) { + return merger.apply(leftValue, rightValue); + } +} \ No newline at end of file -- cgit v1.2.3