From 843329de434bb334d90927c4d22345373a388530 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Tue, 2 Jul 2019 18:05:22 -0400 Subject: Rename package root The package root is now bjc, not io.github.bculkin2442. --- src/main/java/bjc/funcdata/IMap.java | 190 +++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 src/main/java/bjc/funcdata/IMap.java (limited to 'src/main/java/bjc/funcdata/IMap.java') diff --git a/src/main/java/bjc/funcdata/IMap.java b/src/main/java/bjc/funcdata/IMap.java new file mode 100644 index 0000000..ba56578 --- /dev/null +++ b/src/main/java/bjc/funcdata/IMap.java @@ -0,0 +1,190 @@ +package bjc.funcdata; + +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * Functional wrapper over map providing some useful things. + * + * @author ben + * + * @param + * The type of this map's keys. + * + * @param + * The type of this map's values. + */ +public interface IMap { + /** + * Execute an action for each entry in the map. + * + * @param action + * The action to execute for each entry in the map. + */ + void forEach(BiConsumer action); + + /** + * Perform an action for each key in the map. + * + * @param action + * The action to perform on each key in the map. + */ + default void forEachKey(final Consumer action) { + forEach((key, val) -> action.accept(key)); + } + + /** + * Perform an action for each value in the map. + * + * @param action + * The action to perform on each value in the map. + */ + default void forEachValue(final Consumer action) { + forEach((key, val) -> action.accept(val)); + } + + /** + * Check if this map contains the specified key. + * + * @param key + * The key to check. + * + * @return Whether or not the map contains the key. + */ + boolean containsKey(KeyType key); + + /** + * Get the value assigned to the given key. + * + * @param key + * The key to look for a value under. + * + * @return The value of the key. + */ + ValueType get(KeyType key); + + /** + * Get a value from the map, and return a default value if the key + * doesn't exist. + * + * @param key + * The key to attempt to retrieve. + * + * @param defaultValue + * The value to return if the key doesn't exist. + * + * @return The value associated with the key, or the default value if + * the key doesn't exist. + */ + default ValueType getOrDefault(final KeyType key, final ValueType defaultValue) { + try { + return get(key); + } catch(final IllegalArgumentException iaex) { + /* + * We don't care about this, because it indicates a key + * is missing. + */ + return defaultValue; + } + } + + /** + * Add an entry to the map. + * + * @param key + * The key to put the value under. + * + * @param val + * The value to add. + * + * @return The previous value of the key in the map, or null if the key + * wasn't in the map. However, note that it may also return null + * if the key was set to null. + * + * @throws UnsupportedOperationException + * If the map implementation doesn't support modifying the map. + */ + ValueType put(KeyType key, ValueType val); + + /** Delete all the values in the map. */ + default void clear() { + keyList().forEach(key -> remove(key)); + } + + /** + * Get the number of entries in this map. + * + * @return The number of entries in this map. + */ + default int size() { + return keyList().getSize(); + } + + /* + * @NOTE Do we want this to be the semantics for transform, or do we + * want to go to semantics using something like Isomorphism, or doing a + * one-time bulk conversion of the values? + */ + /** + * Transform the values returned by this map. + * + * NOTE: This transform is applied once for each lookup of a value, so + * the transform passed should be a proper function, or things will + * likely not work as expected. + * + * @param + * The new type of returned values. + * + * @param transformer + * The function to use to transform values. + * + * @return The map where each value will be transformed after lookup. + */ + default IMap transform(final Function transformer) { + return new TransformedValueMap<>(this, transformer); + } + + /** + * Extends this map, creating a new map that will delegate queries to + * the map, but store any added values itself. + * + * @return An extended map. + */ + IMap extend(); + + /** + * Remove the value bound to the key. + * + * @param key + * The key to remove from the map. + * + * @return The previous value for the key in the map, or null if the key + * wasn't in the class. NOTE: Just because you received null, + * doesn't mean the map wasn't changed. It may mean that someone + * put a null value for that key into the map. + */ + ValueType remove(KeyType key); + + /** + * Get a list of all the keys in this map. + * + * @return A list of all the keys in this map. + */ + IList keyList(); + + /** + * Get a list of the values in this map. + * + * @return A list of values in this map. + */ + default IList valueList() { + final IList returns = new FunctionalList<>(); + + for(final KeyType key : keyList()) { + returns.add(get(key)); + } + + return returns; + } +} -- cgit v1.2.3