In Python, the defaultdict class provides a convenient way to create a mapping from key -> [list of values], in the following example,
In most common cases where you want a defaultdict, you'll be even happier with a properly designed Multimap or Multiset, which is what you're really looking for. A Multimap is a key -> collection mapping (default is an empty collection) and a Multiset is a key -> int mapping (default is zero).
Guava provides very nice implementations of both Multimaps and Multisets which will cover almost all use cases.
But (and this is why I posted a new answer) with Java 8 you can now replicate the remaining use cases of defaultdict with any existing Map.
If you want to encapsulate these calls you can use Guava's ForwardingMap:
public class DefaultMap extends ForwardingMap {
private final Map delegate;
private final Supplier defaultSupplier;
/**
* Creates a map which uses the given value as the default for all
* keys. You should only use immutable values as a shared default key.
* Prefer {@link #create(Supplier)} to construct a new instance for each key.
*/
public static DefaultMap create(V defaultValue) {
return create(() -> defaultValue);
}
public static DefaultMap create(Supplier defaultSupplier) {
return new DefaultMap<>(new HashMap<>(), defaultSupplier);
}
public DefaultMap(Map delegate, Supplier defaultSupplier) {
this.delegate = Objects.requireNonNull(delegate);
this.defaultSupplier = Objects.requireNonNull(defaultSupplier);
}
@Override
public V get(K key) {
return delegate().computeIfAbsent(key, k -> defaultSupplier.get());
}
}
Then construct your default map like so:
Map> defaultMap = DefaultMap.create(ArrayList::new);