Collections.emptyMap() vs new HashMap()

前端 未结 9 588
南旧
南旧 2020-12-22 21:22

What are some of the situations where I can use Collections.emptyMap() ? The Documentation says I can use this method if I want my collection to be immutable. <

相关标签:
9条回答
  • 2020-12-22 22:15

    For one, you can get away with reference sharing. A new HashMap() etc will require an allocated object, and possibly some extra elements to hold the data, but you only need one copy of an immutable empty collection (list, set, map, or any other such). This makes it an obvious choice when a method you're calling needs to accept a Map but does not need to edit it.

    I suggest checking out Josh Bloch's Effective Java, which lists some very nice attributes of immutable objects (including thread safety).

    0 讨论(0)
  • 2020-12-22 22:16

    Why would I want an immutable empty collection? What is the point?

    There are two different concepts here that appear strange when viewed together. It makes more sense when you treat the two concepts separately.

    • Firstly, you should prefer to use an immutable collection rather than a mutable one wherever possible. The benefits of immuablity are well documented elsewhere.

    • Secondly, you should prefer to use an empty collection rather than to use null as a sentinel. This is well described here. It means that you will have much cleaner, easier to understand code, with fewer places for bugs to hide.

    So when you have code that requires a map, it is better to pass an empty map rather than a null to indicate the absence of a map. And most of the time when you are using a map, it is better to use an immutable map. So this is why there is a convenience function to make an immutable empty map.

    0 讨论(0)
  • 2020-12-22 22:16

    There are couple of cases where you would prefer using immutable maps, lists, sets or other types of collections.

    First and arguably most important use case is whenever you return a result of a query or a computation that would return a set (or list or map) of results, you should prefer to use immutable data structures.

    In this case, I much prefer to return immutable versions of these as this reflects the factual immutability of a resultset of a computation much more clearly - no matter what you do with the data later, the set of results you received from your query should not change.

    Second common use case is when you need to provide an argument as an input to a method or service. Unless you expect the input collection to be modified by the service or method (which is usually a really bad design idea), passing in an immutable collection instead of the mutable one might be the reasonable and safe choice in many cases.

    I think of it as "pass by value" convention.

    More generally - it is a sensible practice to use an immutable data structures whenever data crosses module or service boundaries. This makes it much easier to reason about differences between (immutable) input/output and mutable internal state.

    As a very beneficial side effect of this is increased security and thread safety of your modules/services and ensures cleaner separation of concerns.

    Another good reason to use Collections.empty*() methods is their noticeable lack of verboseness. In pre-Java7 era, if you had a generic collection, you had to sprinkle generic type annotations all over the place.

    Just compare these two declarations:

    Map<Foo, Comparable<? extends Bar>> fooBarMap = new HashMap<Foo, Comparable<? extends Bar>>();
    

    versus:

    Map<Foo, Comparable<? extends Bar>> fooBarMap = Collections.emptyMap();
    

    The latter clearly wins hands-down on readability in two important ways:

    1. In the first declaration, the whole instantiation of an empty map is buried in the noise of generic type declarations, making an essentially trivial declaration much more cryptic than it needs to be.
    2. In addition to notable lack of generic type annotation on the right side, the second version clearly states that the map is initialized to an empty map. In addition - knowing that this method returns an immutable map, it is now easier for me to find where fooBarMap is being assigned another nonempty value just by searching for /fooBarMap =/.
    0 讨论(0)
提交回复
热议问题