Collections.emptyMap() vs new HashMap()

JavaCollections

Java Problem Overview


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.

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

Java Solutions


Solution 1 - Java

From Effective Java, Item #43 - "Return empty arrays or collections, not null" demonstrates returning an empty collection and perhaps even demonstrates using these emptyList(), emptySet(), and emptyMap() methods on the Collections class to get an empty collection that also has the additional benefit of being immutable. From Item #15 "Minimize Mutability".

From Collections-emptySet-Collections-emptyList-Collections
>Its a type of programming idiom. This is for people that do not want null variables. So before the set gets initialized, they can use the empty set.

Note: Below code is just an example (change it according to your use case):

private Set myset = Collections.emptySet();

void initSet() {
   myset = new HashSet();
}
void deleteSet() {
   myset = Collections.emptySet();
}

These methods offer a couple of advantages:

  1. They're more concise because you don't need to explicitly type out the generic type of the collection - it's generally just inferred from the context of the method call.

  2. They're more efficient because they don't bother creating new objects; they just re-use an existing empty and immutable object. This effect is generally very minor, but it's occasionally (well, rarely) important.

Solution 2 - Java

It is, in my personal experience admittedly, very useful in cases where an API requires a collection of parameters, but you have nothing to provide. For example you may have an API that looks something like this, and does not allow null references:

public ResultSet executeQuery(String query, Map<String, Object> queryParameters);

If you have a query that doesn't take any parameters, it's certainly a bit wasteful to create a HashMap, which involves allocating an array, when you could just pass in the 'Empty Map' which is effectively a constant, the way it's implemented in java.util.Collections.

Solution 3 - Java

> 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.

Solution 4 - Java

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 =/.

Solution 5 - Java

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).

Solution 6 - Java

It can be useful when you have a function that returns an immutable collection and in some situation there is no data to return so instead of returning null you can return emptyMap()

It make your code easier and prevent NullPointerException

Solution 7 - Java

Most of the time we use a constructor to create a new empty map. But the Collections methods offer a couple of advantages to create an empty map using static method java.util.Collections.emptyMap()

> 1. They're more concise because you don't need to explicitly type out the generic type of the collection - it's generally just inferred from > the context of the method call. > > 2. They're more efficient because they don't bother creating new objects; they just re-use an existing empty and immutable object. This > effect is generally very minor, but it's occasionally (well, rarely) > important.

Solution 8 - Java

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

For the same reason you'd use Collections.unmodifiableMap() at some point. You want to return a Map instance that throws an exception if the user attempts to modify it. It's just a special case: the empty Map.

Solution 9 - Java

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

For the same reasons why you might want immutable objects. Primarily because you can sleep safe at night in the knowledge that multiple threads can access the same instance of an object and that they will all be seeing the same values. Having no items in a collection is still a valid value, which you would want to maintain.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVinoth Kumar C MView Question on Stackoverflow
Solution 1 - JavaSumit SinghView Answer on Stackoverflow
Solution 2 - JavaAffeView Answer on Stackoverflow
Solution 3 - JavaMarc O'MorainView Answer on Stackoverflow
Solution 4 - JavaRoland TeppView Answer on Stackoverflow
Solution 5 - JavaJeff BowmanView Answer on Stackoverflow
Solution 6 - JavaiTechView Answer on Stackoverflow
Solution 7 - JavasubodhView Answer on Stackoverflow
Solution 8 - JavaRyan StewartView Answer on Stackoverflow
Solution 9 - Javavegemite4meView Answer on Stackoverflow