// uses identity to compare a and new value static class WeakAssoc { O f; // func(A) -> B WeakReference a; B b; *() {} *(O *f) {} synchronized B get(A a) { if (a != (this.a != null ? this.a.get() : null)) { b = (B) callF(f, a); this.a = new WeakReference(a); } ret b; } }