#java #collections #immutability #guava #unmodifiable
#java #Коллекции #неизменяемость #guava #неизменяемый
Вопрос:
Я не уверен, что дефекты неизменяемых коллекций, которые я понимаю, правильные, поэтому я перечисляю их в этом ответе. Надеюсь, что кто-нибудь исправит меня здесь.
a): По сравнению с Collections.unmodifiableXXX(), ImmutableXXX.copyOf() теряет функцию исходной коллекции. Например, когда LinkedList помещается в ImmutableList.copyOf(), ImmutableList больше не связан. То же, что и коллекция на основе дерева.
b): Люди думают, что Collections.unmodifiableXXX просто использует ту же ссылку на исходную коллекцию, поэтому, как только исходная коллекция изменяется, Collections.unmodifiableXXX также изменяется. Но мое решение состоит в том, чтобы обернуть исходную коллекцию во временную коллекцию, которая передается в ImmutableXXX.copyOf(). Смотрите код ниже:
List<String> l = new ArrayList<String>();
List<String> unmodifiableList = Collections.unmodifiableList(l);
ImmutableList<String> immutableList= ImmutableList.copyOf(l);
l.add("a");//unmodifiableList is also added "a", immutableList not.
/*My solution as follows:
So unmodifiableList2 is also immutable as ImmutableList.copyOf(l) does*/
List<String> unmodifiableList2= Collections.unmodifiableList(new ArrayList(l));
Каково ваше понимание неизменяемой коллекции? Спасибо!
Ответ №1:
Ничто из того, что вы упомянули, не является «дефектом».
a) Совершенно не имеет значения, что ImmutableList
больше не является связанным списком. Единственные преимущества связанного списка перед списком на основе массива включают добавление и удаление элементов (удаление в первую очередь). Вы не можете добавлять в неизменяемый список или удалять из него, поэтому использование массива предпочтительнее из-за быстрого произвольного доступа, а также эффективности использования памяти.
Для чего-то подобного TreeSet
необходимо учитывать ряд моментов.
- Нормальный
ImmutableSet
сохраняет порядок итерации заданных элементов. Итак, если у вас естьTreeSet
и вы используетеImmutableSet.copyOf
для создания неизменяемой копии, скопированные элементы будут упорядочены так же, как в оригинале. ImmutableSortedSet
является неизменяемым эквивалентомTreeSet
и использует естественный порядок элементов илиComparator
точно так же, какTreeSet
это делает.
б) Тот факт, что вы можете создать List
, который оказывается неизменяемым, без использования Guava, ничего не меняет. Неизменяемые коллекции Guava разработаны специально с учетом неизменяемости и благодаря этому имеют различные преимущества, в том числе (но не ограничиваясь ими):
- Тот факт, что их неизменяемость гарантируется на уровне типа, как я упоминал в своем ответе на ваш последний вопрос. Когда ваш метод возвращает что-то типа
ImmutableSet
, вызывающий знает, что set не может для них измениться. Не так, если он просто возвращаетSet
. - Оптимизация памяти, включая синглтоны для пустых случаев и специальные классы для одноэлементных случаев.
ImmutableSet.copyOf
и т.д. На самом деле ничего не копируйте, если входные данные уже являются неизменяемым экземпляром того же типа.- Методы / конструкторы, упрощающие создание неизменяемых коллекций.
Комментарии:
1. Проницательный ответ. Спасибо!
Ответ №2:
зачем нам нужны неизменяемые коллекции
- Это значительно упрощает параллельное программирование. Подумайте об этом, почему сложно писать правильное многопоточное программирование? Потому что сложно синхронизировать доступ потоков к заданному ресурсу (в данном случае к списку).
Ответ №3:
Колинд и Амир напрямую ответили на ваши конкретные вопросы, но вы, возможно, также захотите взглянуть на GTUG — Использование библиотеки Google Collections для Java (1 из 2) — презентацию о неизменяемых коллекциях Кевина Бурриллиона (ведущего разработчика Guava), где он объясняет все преимущества неизменяемых коллекций.
Хотя презентации два года и она посвящена «Коллекциям Google» (которые сейчас являются подразделом Guava), это очень интересная презентация. API, возможно, немного изменился с момента презентации, потому что API Google Collections в то время был в бета-версии, но большинство концепций остались прежними.