package com.baeldung.guava; import com.google.common.base.Function; import java.util.*; public class GuavaMapFromSet extends AbstractMap { private class SingleEntry implements Entry { private K key; public SingleEntry(K key) { this.key = key; } @Override public K getKey() { return this.key; } @Override public V getValue() { V value = GuavaMapFromSet.this.cache.get(this.key); if (value == null) { value = GuavaMapFromSet.this.function.apply(this.key); GuavaMapFromSet.this.cache.put(this.key, value); } return value; } @Override public V setValue(V value) { throw new UnsupportedOperationException(); } } private class MyEntrySet extends AbstractSet> { public class EntryIterator implements Iterator> { private Iterator inner; public EntryIterator() { this.inner = MyEntrySet.this.keys.iterator(); } @Override public boolean hasNext() { return this.inner.hasNext(); } @Override public Map.Entry next() { K key = this.inner.next(); return new SingleEntry(key); } @Override public void remove() { throw new UnsupportedOperationException(); } } private Set keys; public MyEntrySet(Set keys) { this.keys = keys; } @Override public Iterator> iterator() { return new EntryIterator(); } @Override public int size() { return this.keys.size(); } } private WeakHashMap cache; private Set> entries; private Function function; public GuavaMapFromSet(Set keys, Function function) { this.function = function; this.cache = new WeakHashMap(); this.entries = new MyEntrySet(keys); } @Override public Set> entrySet() { return this.entries; } }