// should be thread-safe by nature // compare efficiently due to md5 caching // tested with A = S static class ImmL extends AbstractList { new L l; int hash; S md5; *() {} *(L _l) { l.addAll(_l); } // List methods public int size() { ret l.size(); } public A get(int i) { ret l.get(i); } public synchronized int hashCode() { if (hash == 0) hash = l.hashCode(); ret hash; } public bool equals(O o) { if (o instanceof ImmL && neq(md5(), ((ImmL) o).md5())) false; ret super.equals(o); } public synchronized S md5() { if (md5 == null) md5 = main.md5(structure(l)); ret md5; } }