As @AntonH mentioned, Map
is the interface and HashMap
is a concrete implementation of that interface.
To answer the final part of your question, the benefit to doing this is that it makes your code more flexible for no cost. It means that any implementation of the interface can be "plugged in" at the point where it's constructed, and the rest of the code doesn't have to change.
This applies not only to alternative implementations in the core library (HashMap
vs TreeMap
, for example); but to other custom implementations too (someone might write a ListeningMap
which has hooks to be notified when an entry is added, for example).
If you wrote a method to accept a HashMap
argument, then people could only ever pass it HashMaps. It would force callers to adopt a particular data storage, or have the overhead of casting every time they called it. And it would prevent them from doing any interesting logic (such as the aforementioned listeners, or a Map
that calculates its entries dynamically).
So unless you really, specifically need for the value to be a HashMap (which is almost never the case), declaring your types as the broadest possible interface gives a lot of flexibility.