[java] What is the difference between the HashMap and Map objects in Java?

What is the difference between the following maps I create (in another question, people answered using them seemingly interchangeably and I'm wondering if/how they are different):

HashMap<String, Object> map = new HashMap<String, Object>();
Map<String, Object> map = new HashMap<String, Object>();

This question is related to java dictionary hashmap

The answer is


Map is interface and Hashmap is a class that implements Map Interface


Adding to the top voted answer and many ones above stressing the "more generic, better", I would like to dig a little bit more.

Map is the structure contract while HashMap is an implementation providing its own methods to deal with different real problems: how to calculate index, what is the capacity and how to increment it, how to insert, how to keep the index unique, etc.

Let's look into the source code:

In Map we have the method of containsKey(Object key):

boolean containsKey(Object key);

JavaDoc:

boolean java.util.Map.containsValue(Object value)

Returns true if this map maps one or more keys to the specified value. More formally, returns true if and only if this map contains at least one mapping to a value v such that (value==null ? v==null : value.equals(v)). This operation will probably require time linear in the map size for most implementations of the Map interface.

Parameters:value

value whose presence in this map is to betested

Returns:true

if this map maps one or more keys to the specified

valueThrows:

ClassCastException - if the value is of an inappropriate type for this map (optional)

NullPointerException - if the specified value is null and this map does not permit null values (optional)

It requires its implementations to implement it, but the "how to" is at its freedom, only to ensure it returns correct.

In HashMap:

public boolean containsKey(Object key) {
    return getNode(hash(key), key) != null;
}

It turns out that HashMap uses hashcode to test if this map contains the key. So it has the benefit of hash algorithm.


I was just going to do this as a comment on the accepted answer but it got too funky (I hate not having line breaks)

ah, so the difference is that in general, Map has certain methods associated with it. but there are different ways or creating a map, such as a HashMap, and these different ways provide unique methods that not all maps have.

Exactly--and you always want to use the most general interface you possibly can. Consider ArrayList vs LinkedList. Huge difference in how you use them, but if you use "List" you can switch between them readily.

In fact, you can replace the right-hand side of the initializer with a more dynamic statement. how about something like this:

List collection;
if(keepSorted)
    collection=new LinkedList();
else
    collection=new ArrayList();

This way if you are going to fill in the collection with an insertion sort, you would use a linked list (an insertion sort into an array list is criminal.) But if you don't need to keep it sorted and are just appending, you use an ArrayList (More efficient for other operations).

This is a pretty big stretch here because collections aren't the best example, but in OO design one of the most important concepts is using the interface facade to access different objects with the exact same code.

Edit responding to comment:

As for your map comment below, Yes using the "Map" interface restricts you to only those methods unless you cast the collection back from Map to HashMap (which COMPLETELY defeats the purpose).

Often what you will do is create an object and fill it in using it's specific type (HashMap), in some kind of "create" or "initialize" method, but that method will return a "Map" that doesn't need to be manipulated as a HashMap any more.

If you ever have to cast by the way, you are probably using the wrong interface or your code isn't structured well enough. Note that it is acceptable to have one section of your code treat it as a "HashMap" while the other treats it as a "Map", but this should flow "down". so that you are never casting.

Also notice the semi-neat aspect of roles indicated by interfaces. A LinkedList makes a good stack or queue, an ArrayList makes a good stack but a horrific queue (again, a remove would cause a shift of the entire list) so LinkedList implements the Queue interface, ArrayList does not.


Map is the Interface and Hashmap is the class that implements that.

So in this implementation you create the same objects


enter image description here

Map has the following implementations:

  1. HashMap Map m = new HashMap();

  2. LinkedHashMap Map m = new LinkedHashMap();

  3. Tree Map Map m = new TreeMap();

  4. WeakHashMap Map m = new WeakHashMap();

Suppose you have created one method (this is just pseudocode).

public void HashMap getMap(){
   return map;
}

Suppose your project requirements change:

  1. The method should return map contents - Need to return HashMap.
  2. The method should return map key's in insertion order - Need to change return type HashMap to LinkedHashMap.
  3. The method should return map key's in sorted order - Need to change return type LinkedHashMap to TreeMap.

If your method returns specific classes instead of something that implements the Map interface, you have to change the return type of getMap() method each time.

But if you use the polymorphism feature of Java, and instead of returning specific classes, use the interface Map, it improves code reusability and reduces the impact of requirement changes.


HashMap<String, Object> map1 = new HashMap<String, Object>();
Map<String, Object> map2 = new HashMap<String, Object>();  

First of all Map is an interface it has different implementation like - HashMap, TreeHashMap, LinkedHashMap etc. Interface works like a super class for the implementing class. So according to OOP's rule any concrete class that implements Map is a Map also. That means we can assign/put any HashMap type variable to a Map type variable without any type of casting.

In this case we can assign map1 to map2 without any casting or any losing of data -

map2 = map1

In your second example the "map" reference is of type Map, which is an interface implemented by HashMap (and other types of Map). This interface is a contract saying that the object maps keys to values and supports various operations (e.g. put, get). It says nothing about the implementation of the Map (in this case a HashMap).

The second approach is generally preferred as you typically wouldn't want to expose the specific map implementation to methods using the Map or via an API definition.


You create the same maps.

But you can fill the difference when you will use it. With first case you'll be able to use special HashMap methods (but I don't remember anyone realy useful), and you'll be able to pass it as a HashMap parameter:

public void foo (HashMap<String, Object) { ... }

...

HashMap<String, Object> m1 = ...;
Map<String, Object> m2 = ...;

foo (m1);
foo ((HashMap<String, Object>)m2); 

Map is the static type of map, while HashMap is the dynamic type of map. This means that the compiler will treat your map object as being one of type Map, even though at runtime, it may point to any subtype of it.

This practice of programming against interfaces instead of implementations has the added benefit of remaining flexible: You can for instance replace the dynamic type of map at runtime, as long as it is a subtype of Map (e.g. LinkedHashMap), and change the map's behavior on the fly.

A good rule of thumb is to remain as abstract as possible on the API level: If for instance a method you are programming must work on maps, then it's sufficient to declare a parameter as Map instead of the stricter (because less abstract) HashMap type. That way, the consumer of your API can be flexible about what kind of Map implementation they want to pass to your method.


Map is an interface that HashMap implements. The difference is that in the second implementation your reference to the HashMap will only allow the use of functions defined in the Map interface, while the first will allow the use of any public functions in HashMap (which includes the Map interface).

It will probably make more sense if you read Sun's interface tutorial


HashMap is an implementation of Map so it's quite the same but has "clone()" method as i see in reference guide))


As noted by TJ Crowder and Adamski, one reference is to an interface, the other to a specific implementation of the interface. According to Joshua Block, you should always attempt to code to interfaces, to allow you to better handle changes to underlying implementation - i.e. if HashMap suddenly was not ideal for your solution and you needed to change the map implementation, you could still use the Map interface, and change the instantiation type.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to dictionary

JS map return object python JSON object must be str, bytes or bytearray, not 'dict Python update a key in dict if it doesn't exist How to update the value of a key in a dictionary in Python? How to map an array of objects in React C# Dictionary get item by index Are dictionaries ordered in Python 3.6+? Split / Explode a column of dictionaries into separate columns with pandas Writing a dictionary to a text file? enumerate() for dictionary in python

Examples related to hashmap

How to split a string in two and store it in a field Printing a java map Map<String, Object> - How? Hashmap with Streams in Java 8 Streams to collect value of Map How to convert String into Hashmap in java Convert object array to hash map, indexed by an attribute value of the Object HashMap - getting First Key value The type java.util.Map$Entry cannot be resolved. It is indirectly referenced from required .class files Sort Go map values by keys Print all key/value pairs in a Java ConcurrentHashMap creating Hashmap from a JSON String