Vinoth Kumar C M
Vinoth Kumar C M

Reputation: 10588

Collections.emptyMap() vs new HashMap()

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?

Upvotes: 163

Views: 67919

Answers (8)

Marc O'Morain
Marc O'Morain

Reputation: 3759

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.

Upvotes: 26

Roland Tepp
Roland Tepp

Reputation: 8511

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

Upvotes: 8

vegemite4me
vegemite4me

Reputation: 6856

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.

Upvotes: 1

subodh
subodh

Reputation: 6158

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.

Upvotes: 3

iTech
iTech

Reputation: 18440

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

Upvotes: 3

Jeff Bowman
Jeff Bowman

Reputation: 95614

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

Upvotes: 5

Ryan Stewart
Ryan Stewart

Reputation: 128779

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.

Upvotes: 2

Affe
Affe

Reputation: 47954

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.

Upvotes: 35

Related Questions