summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/funcdata
diff options
context:
space:
mode:
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/funcdata')
-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
7 files changed, 287 insertions, 125 deletions
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);
+ });
+ }
+ }
}