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