FnAsMap.java
package no.motif.maps;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import no.motif.f.Fn;
class FnAsMap<K, V> implements Map<K, V> {
private final Fn<K, V> fn;
private final Map<Object, V> overrides;
private final Map<Object, V> removed;
FnAsMap(Fn<K, V> fn) {
this.fn = fn;
this.overrides = new HashMap<>();
this.removed = new HashMap<>();
}
@Override
public boolean containsKey(Object key) {
@SuppressWarnings("unchecked")
K castedKey = (K) key;
return !removed.containsKey(key) && (overrides.containsKey(key) || fn.$(castedKey) != null);
}
@Override
public V get(Object key) {
if (overrides.containsKey(key)) return overrides.get(key);
if (removed.containsKey(key)) return null;
@SuppressWarnings("unchecked")
K castedKey = (K) key;
return fn.$(castedKey);
}
@Override
public V put(K key, V value) {
V previous = get(key);
removed.remove(key);
overrides.put(key, value);
return previous;
}
@Override
public V remove(Object key) {
V previous = get(key);
removed.put(key, previous);
overrides.remove(key);
return previous;
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
for (Map.Entry<? extends K, ? extends V> entry : m.entrySet()) {
put(entry.getKey(), entry.getValue());
}
}
@Override
public void clear() {
overrides.clear();
removed.clear();
}
@Override
public int size() {
throw new NotPossibleOnMapViewOfFn(fn, "the size cannot be determined"); }
@Override
public boolean isEmpty() {
throw new NotPossibleOnMapViewOfFn(fn, "it cannot be determined if it is empty"); }
@Override
public boolean containsValue(Object v) {
throw new NotPossibleOnMapViewOfFn(fn, "it cannot be determined if it contains the value '" + v + "'"); }
@Override
public Set<K> keySet() {
throw new NotPossibleOnMapViewOfFn(fn, "it is not possible derive a set of keys."); }
@Override
public Collection<V> values() {
throw new NotPossibleOnMapViewOfFn(fn, "it is not possible resolve the values."); }
@Override
public Set<Map.Entry<K, V>> entrySet() {
throw new NotPossibleOnMapViewOfFn(fn, "it is not possible derive the entries."); }
}