What's the difference between Collections.unmodifiableSet() and ImmutableSet of Guava?

后端 未结 4 1179
迷失自我
迷失自我 2020-12-13 05:57

JavaDoc of ImmutableSet says:

Unlike Collections.unmodifiableSet, which is a view of a separate collection that can sti

相关标签:
4条回答
  • 2020-12-13 06:38

    Kevin Bourrillion (Guava lead developer) compares immutable / unmodifiable collections in this presentation. While the presentation is two years old, and focuses on "Google Collections" (which is now a subpart of Guava), this is a very interesting presentation. The API may have changed here and there (the Google Collections API was in Beta at the time), but the concepts behind Google Collections / Guava are still valid.

    You might also be interested in this other SO question ( What is the difference between google's ImmutableList and Collections.unmodifiableList() ).

    0 讨论(0)
  • 2020-12-13 06:42

    Besides the behavioral difference that Jon mentions, an important difference between ImmutableSet and the Set created by Collections.unmodifiableSet is that ImmutableSet is a type. You can pass one around and have it remain clear that the set is immutable by using ImmutableSet rather than Set throughout the code. With Collections.unmodifiableSet, the returned type is just Set... so it's only clear that the set is unmodifiable at the point where it is created unless you add Javadoc everywhere you pass that Set saying "this set is unmodifiable".

    0 讨论(0)
  • 2020-12-13 06:47

    A difference between the two not stated in other answers is that ImmutableSet does not permit null values, as described in the Javadoc

    A high-performance, immutable Set with reliable, user-specified iteration order. Does not permit null elements.

    (The same restriction applies to values in all Guava immutable collections.)

    For example:

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

    All of these fail at runtime. In contrast:

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

    This is fine.

    0 讨论(0)
  • 2020-12-13 06:54

    Consider this:

    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
    

    In other words, ImmutableSet is immutable despite whatever collection it's built from potentially changing - because it creates a copy. Collections.unmodifiableSet prevents the returned collection from being directly changed, but it's still a view on a potentially-changing backing set.

    Note that if you start changing the contents of the objects referred to by any set, all bets are off anyway. Don't do that. Indeed, it's rarely a good idea to create a set using a mutable element type in the first place. (Ditto maps using a mutable key type.)

    0 讨论(0)
提交回复
热议问题