package bjc.functypes; import java.util.*; import java.util.function.Function; import bjc.funcdata.Freezable; import bjc.funcdata.ObjectFrozen; /** * Functional interface for a generic builder using a map * * @author bjcul * * @param Key type of the map * @param Value type of the map * @param Result type of the builder */ public interface MapBuilder extends Freezable> { /** * Build an instance using the current map * * @return An instance constructed using the map */ R build(); /** * Add a value to the map * * @param key The key to add * @param value The value to add * * @return The builder, for chaining */ MapBuilder add(K key, V value); /** * Remove a value from the map * * @param key The key to remove * * @return The removed value */ V remove(K key); /** * Clear the contents of the map */ void clear(); /** * Get the internal map. * * @return The internal map */ Map getMap(); /** * Create a new map-builder from a function * * @param The key type of the map * @param The value type of the map * @param The result of the builder * * @param f The building function * * @return A map-builder using the function */ static MapBuilder from(Function, R> f) { return new FunctionalMapBuilder<>(f); } } final class FunctionalMapBuilder implements MapBuilder { private final Function, R> f; private Map mep = new HashMap<>(); private boolean frozen = false; FunctionalMapBuilder(Function, R> f) { this.f = f; } @Override public R build() { return f.apply(mep); } @Override public MapBuilder add(K key, V value) { if (frozen) throw new ObjectFrozen(); mep.put(key, value); return this; } @Override public V remove(K key) { if (frozen) throw new ObjectFrozen(); return mep.remove(key); } @Override public void clear() { if (frozen) throw new ObjectFrozen(); mep.clear(); } @Override public Map getMap() { if (frozen) return Collections.unmodifiableMap(mep); return mep; } @Override public boolean freeze() { frozen = true; return true; } @Override public boolean thaw() { frozen = false; return true; } @Override public boolean isFrozen() { return frozen; } }