sclass ValueOnDemandMap extends AbstractMap {
Set keys; // keys may be changed if map is changed
IF1 makeValue;
*() {}
*(Set *keys, IF1 *makeValue) {} // doesn't clone keys
public B get(O a) {
ret !containsKey(a) ? null : makeValue.get((A) a);
}
public bool containsKey(O a) {
ret keys.contains(a);
}
public Set> entrySet() {
ret new EntrySet;
}
final class EntrySet extends AbstractSet> {
public final int size() { ret keys.size(); }
public final void clear() { keys.clear(); }
public final Iterator> iterator() {
return mapI(keys.iterator(), key -> new Map.Entry() {
public A getKey() { ret key; }
public B getValue() { ret makeValue.get(key); }
public B setValue(B newValue) {
throw unimplemented();
}
});
}
public final boolean contains(Object o) {
if (o cast Map.Entry)
ret keys.contains(o.getKey());
false;
}
public final boolean remove(Object o) {
if (o cast Map.Entry)
ret keys.remove(o.getKey());
false;
}
}
public Set keySet() { ret keys; }
public int size() { ret keys.size(); }
}