Add an immutable computing map
See original GitHub issue(Sorry, hit post
by mistake, and the initial post was empty. Edited afterwards.)
Please consider providing an ImmutableMap
that works by computing only once the value associated to each key, lazily, and storing the result. Concretely, I propose to add: Maps#immutableComputingMap(Set<K> keys, Function<K, V> valueProvider): ImmutableMap<K, V>
. The returned map has a constant keySet()
, the one given by the keys
parameter at creation time (defensively copied, of course). The returned map behaves as follows: if the value corresponding to some key was never computed yet, compute it using the given function and store the result when needed (lazily); if it ever was, return that previously computed result.
The returned map is indeed immutable in the sense that all the calls on the map are idempotent: calling a given method with given parameters twice always returns the same result.
Use case: a class provides a getSomeData(): ImmutableMap<K, V>
(for some K, V
) under the form of a map, that is (in some cases) slow to compute. Initially the whole map is computed at once when getSomeData()
is called. The designer of the class later wants to change it, upon realizing that in some use cases only a small subset of the keys is used by the callers of that method. Thus, the designer wants to compute the values lazily, only when get(k)
is called on the returned map.
This idea is not to be mixed up with similar ideas that have been rejected because they do not satisfy the map contract. This proposal does satisfy the map contract, as far as I can see.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:2
- Comments:9 (4 by maintainers)
Top GitHub Comments
@oliviercailloux If
ImmutableMap
involved lazy computing, I wouldn’t trust anyImmutableMap
returned by any API ever again. “Is it safe to pass on?”, “Should I iterate overvalues()
to trigger loading first?” and so on. I know that it is not specified directly to be so, but most of the times I treat “immutable” as “set in stone”.It is pretty easy to get computing map already using guava cache or caffeine like this:
You can make it more immutable-like by taking
ImmutableSet<K>
instead ofSet<K>
.In the description, a call like
size()
orkeySet()
would change over time. It would therefore not be immutable, but would be not directly modifiable. Instead it seems like @perceptron8 sample, wrapped withCollections.unmodifiableMap
, would serve this purpose and require no library changes.