"Modificar" eficientemente um ImmutableMap

No momento, estamos usando o Guava para suas coleções imutáveis, mas fiquei surpreso ao descobrir que seus mapas não têm métodos para criar facilmente novos mapas com pequenas modificações. Além disso, o construtor não permite atribuir novos valores às chaves ou remover chave

Então, se eu quiser modificar apenas um valor, eis o que eu gostaria de poder fazer:

ImmutableMap<Guid, ImmutableMap<String, Integer>> originalMap = /* get the map */;
ImmutableMap<Guid, ImmutableMap<String, Integer>> modifiedMap =
    originalMap.cloneAndPut(key, value);

Aqui está o que parece que a Goiaba espera que eu faça:

ImmutableMap<Guid, ImmutableMap<String, Integer>> originalMap = /* get the map */;
Map<Guid, ImmutableMap<String, Integer>> mutableCopy = new LinkedHashMap<>(originalMap);
mutableCopy.put(key, value);
originalMap = ImmutableMap.copyOf(mutableCopy);
/* put the map back */

Ao fazer isso, recebo uma nova cópia do mapa com a modificação que desejo. A cópia original não foi tocada e eu usarei uma referência atômica para colocar a coisa de volta, para que toda a instalação seja segura para threads.

É apenas lento.

Há muitas cópias desperdiçadas por baixo das capas aqui. Suponha que haja 1.024 baldes no mapa. São 1.023 baldes que você desnecessariamente cria novamente (duas vezes cada) também, quando você poderia ter usado esses baldes imutáveis como estão e clonado apenas um deles.

Então eu acho

Existe um método utilitário Guava enterrado em algum lugar para esse tipo de coisa? (Não está no Maps ou no ImmutableMap.Builder.)

Existe alguma outra biblioteca Java que acerte esse tipo de coisa? Tenho a impressão de que Clojure tem esse tipo de coisa por trás, mas ainda não estamos prontos para mudar de idioma ...

questionAnswers(2)

yourAnswerToTheQuestion