// doesn't implement all methods yet 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 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 final Spliterator> spliterator() { return new EntrySpliterator<>(HashMap.this, 0, -1, 0, 0); } public final void forEach(Consumer> action) { Node[] tab; if (action == null) throw new NullPointerException(); if (size > 0 && (tab = table) != null) { int mc = modCount; for (Node e : tab) { for (; e != null; e = e.next) action.accept(e); } if (modCount != mc) throw new ConcurrentModificationException(); } }*/ } public Set keySet() { ret keys; } public int size() { ret keys.size(); } }