В настоящее время мы используем Guava для его неизменных коллекций, но я с удивлением обнаружил, что на их картах нет методов, позволяющих легко создавать новые карты с незначительными изменениями. Кроме того, их конструктор не позволяет назначать новые значения ключам или удалять ключи.
Итак, если бы я хотел изменить только одно значение, вот что я хотел бы сделать:
ImmutableMap<Guid, ImmutableMap<String, Integer>> originalMap = /* get the map */;
ImmutableMap<Guid, ImmutableMap<String, Integer>> modifiedMap =
originalMap.cloneAndPut(key, value);
Вот что, похоже, Гуава ожидает от меня:
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 */
Делая это, я получаю новую копию карты с желаемой модификацией. Оригинальная копия не тронута, и я буду использовать атомарную ссылку, чтобы вернуть вещь обратно, чтобы вся установка была поточно-ориентированной.
Это просто медленно.
Здесь происходит много потерянного копирования. Предположим, на карте есть 1024 ведра. Это 1023 сегмента, которые вы без необходимости создаете заново (по два раза в каждом), когда вы могли использовать эти неизменяемые сегменты как есть и клонировать только один из них.
Итак, я думаю:
Есть ли где-нибудь метод утилит Guava для такого рода вещей? (Это не в Картах или ImmutableMap.Builder.)
Есть ли какая-либо другая библиотека Java, которая правильно понимает подобные вещи? У меня сложилось впечатление, что у Clojure есть такая штука под капотом, но мы пока не готовы переключать языки ...