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(); } }