Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collections.emptyMap() vs new HashMap()

People also ask

What is collections emptyMap?

The emptyMap() method of Java Collections is a method that is used to return an empty map such that we can not change the data in map IE it is immutable. Syntax: public static final <Key,Value> Map<Key,Value> emptyMap() where, key is the key element. value is the value element.

How do I return an empty HashMap?

isEmpty() method of HashMap class is used to check for the emptiness of the map. The method returns True if no key-value pair or mapping is present in the map else False. Parameters: The method does not take any parameters.

What is the use of empty map?

The emptyMap and the immutableMap can be used to create objects, that are immutable. emptyMap is the initial point. Each time an element is added the map itself is replaced by a map containing the old element and the new elements. The point is, that accesses to the object are safe.

How do you initialize an empty map?

For initializing an empty Map, we'll not pass any key-value pair in this method: Map<String, String> emptyMapUsingJava9 = Map. of(); This factory method produces an immutable Map, hence we'll not be able to add, delete or modify any key-value pair.


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.


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.


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.


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

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


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