Эффективно «модифицируя» ImmutableMap - PullRequest
13 голосов
/ 01 февраля 2012

В настоящее время мы используем 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 сегмента, которые вы без необходимости создаете заново (по два раза в каждом), когда вы могли использовать эти неизменяемые сегменты как есть и клонировать только один из них.

Итак, я думаю:

  1. Есть ли где-нибудь метод утилит Guava для такого рода вещей? (Это не в Картах или ImmutableMap.Builder.)

  2. Есть ли какая-либо другая библиотека Java, которая правильно понимает подобные вещи? У меня сложилось впечатление, что у Clojure есть такая штука под капотом, но мы пока не готовы переключать языки ...

1 Ответ

6 голосов
/ 01 февраля 2012

Немного неожиданно, что карта функциональной Java изменчива, как карта Гуавы. Хотя этот список неизменен, как я и ожидал.

Погуглил для "персистентной коллекции Java": pcollections. Есть Карта реализации .

Прежде чем использовать любую другую реализацию, я бы сравнил характеристики памяти и производительности с Guava. Я не удивлюсь, если все еще будет лучше.

...