В чем разница между Collections.unmodifiableSet () и ImmutableSet из Guava? - PullRequest
39 голосов
/ 10 апреля 2011

JavaDoc из ImmutableSet говорит:

В отличие от Collections.unmodifiableSet, который является представлением отдельной коллекции, которая все еще может изменяться, экземпляр этого класса содержит свои собственные личные данныеи никогда не изменится.Этот класс удобен для общедоступных статических финальных наборов («константных наборов»), а также позволяет легко сделать «защитную копию» набора, предоставленного вашему классу вызывающим абонентом.

НоImmutableSet все еще хранит ссылку на элементы, я не могу понять разницу с Collections.unmodifiableSet().Образец:

StringBuffer s=new StringBuffer("a");
ImmutableSet<StringBuffer> set= ImmutableSet.of(s);
s.append("b");//s is "ab", s is still changed here!

Может кто-нибудь объяснить это?

Ответы [ 4 ]

79 голосов
/ 10 апреля 2011

Учтите это:

Set<String> x = new HashSet<String>();
x.add("foo");

ImmutableSet<String> guava = ImmutableSet.copyOf(x);
Set<String> builtIn = Collections.unmodifiableSet(x);

x.add("bar");
System.out.println(guava.size()); // Prints 1
System.out.println(builtIn.size()); // Prints 2

Другими словами, ImmutableSet является неизменным, независимо от того, какую коллекцию он построил из-за возможного изменения - потому что он создает копию.Collections.unmodifiableSet предотвращает прямое изменение коллекции , возвращенной , но это все еще вид на потенциально изменяющийся набор резервных копий.

Обратите внимание, что если вы начнете изменять содержимое объектов ссылается на любой сет, все ставки в любом случае отключены.Не делай этого.Действительно, редко бывает хорошей идеей создавать набор с использованием изменяемого типа элемента.(То же самое сопоставляется с использованием изменяемого типа ключа.)

15 голосов
/ 10 апреля 2011

Помимо поведенческого различия, которое упоминает Джон, важное различие между ImmutableSet и Set, созданным Collections.unmodifiableSet, заключается в том, что ImmutableSet - это тип . Вы можете обойти его, оставив ясным, что набор неизменен, используя ImmutableSet вместо Set во всем коде. С Collections.unmodifiableSet возвращаемый тип - просто Set ... поэтому ясно, что набор не может быть изменен в той точке, где он был создан, если вы не добавите Javadoc везде, где вы передаете этот Set, говоря «этот набор не изменяем» .

10 голосов
/ 10 апреля 2011

Кевин Бурриллион (ведущий разработчик Guava) сравнивает неизменяемые / неизменяемые коллекции в этой презентации . В то время как презентации два года, и она ориентирована на «Коллекции Google» (которая теперь является частью Guava), это очень интересная презентация 1004 *. API мог измениться здесь и там (API Google Collections был в бета-версии в то время), но концепции, лежащие в основе Google Collections / Guava, все еще действительны.

Вас также может заинтересовать этот другой вопрос SO ( В чем разница между ImmutableList от Google и Collections.unmodifiableList () ).

3 голосов
/ 22 апреля 2016

Разница между двумя, не указанными в других ответах, заключается в том, что ImmutableSet не допускает null значений, как описано в Javadoc

Высокопроизводительный неизменяемый набор с надежным, заданным пользователем порядком итераций. Не разрешает нулевые элементы.

(То же ограничение применяется к значениям во всех неизменяемых коллекциях гуавы.)

Например:

ImmutableSet.of(null);
ImmutableSet.builder().add("Hi").add(null); // Fails in the Builder.
ImmutableSet.copyOf(Arrays.asList("Hi", null));

Все они терпят неудачу во время выполнения. Для сравнения:

Collections.unmodifiableSet(new HashSet<>(Arrays.asList("Hi", null)));

Это хорошо.

...