Rectangle 27 0

dictionary What is the difference between the HashMap and Map objects in Java?


Foo
SpecialFoo
class Foo {
    private HashMap<String, Object> things;
    private HashMap<String, Object> moreThings;

    protected HashMap<String, Object> getThings() {
        return this.things;
    }

    protected HashMap<String, Object> getMoreThings() {
        return this.moreThings;
    }

    public Foo() {
        this.things = new HashMap<String, Object>();
        this.moreThings = new HashMap<String, Object>();
    }

    // ...more...
}
class Foo {
    private Map<String, Object> things;             // <== Changed
    private Map<String, Object> moreThings;         // <== Changed

    protected Map<String, Object> getThings() {     // <== Changed
        return this.things;
    }

    protected Map<String, Object> getMoreThings() { // <== Changed
        return this.moreThings;
    }

    public Foo() {
        this.things = new HashMap<String, Object>();
        this.moreThings = new HashMap<String, Object>();
    }

    // ...more...
}
class SpecialFoo extends Foo {
    private void doSomething(Map<String, Object> t) { // <== Changed
        // ...
    }

    public void whatever() {
        this.doSomething(this.getThings());
        this.doSomething(this.getMoreThings());
    }
}

I think what he's saying is that even if you're referring to a HashMap as a Map, the implementation remains HashMap and so nothing changes about how the methods execute. If you changed the implementation behind the Map interface, properties of execution (such as speed) could indeed change.

If I had done that, then Mary would have done this:

Interfaces (and base classes) let us reveal only as much as is necessary, keeping our flexibility under the covers to make changes as appropriate. In general, we want to have our references be as basic as possible. If we don't need to know it's a HashMap, just call it a Map.

Later, I decide that actually, it's better if I use TreeMap instead of HashMap in Foo. I update Foo, changing HashMap to TreeMap. Now, SpecialFoo doesn't compile anymore, because I've broken the contract: Foo used to say it provided HashMaps, but now it's providing TreeMaps instead. So we have to fix SpecialFoo now (and this kind of thing can ripple through a codebase).

Later, Mary writes code subclassing it. She has something she needs to do with both things and moreThings, so naturally she puts that in a common method, and she uses the same type I used on getThings/getMoreThings when defining her method:

Note how I'm now using Map<String, Object> everywhere I can, only being specific when I create the actual objects.

Sometimes you can't do that, sometimes you have to be specific. But unless you have a reason to be, err toward the least-specific interface.

The advantage to using Map<String, Object> is that you can change the underlying object to be a different kind of map without breaking your contract with any code that's using it. If you declare it as HashMap<String, Object>, you have to change your contract if you want to change the underlying implementation.

The class has a couple of internal maps of string->object which it shares (via accessor methods) with subclasses. Let's say I write it with HashMaps to start with because I think that's the appropriate structure to use when writing the class.

There is no difference between the objects; you have a HashMap<String, Object> in both cases. There is a difference in the interface you have to the object. In the first case, the interface is HashMap<String, Object>, whereas in the second it's Map<String, Object>. But the underlying object is the same.

This is a great answer. It would be even better with examples.

This isn't a blind rule, but in general, coding to the most general interface is going to be less brittle than coding to something more specific. If I'd remembered that, I wouldn't have created a Foo that set Mary up for failure with SpecialFoo. If Mary had remembered that, then even though I messed up Foo, she would have declared her private method with Map instead of HashMap and my changing Foo's contract wouldn't have impacted her code.

Unless I had a really good reason for sharing that my implementation was using a HashMap (and that does happen), what I should have done was declare getThings and getMoreThings as just returning Map<String, Object> without being any more specific than that. In fact, barring a good reason to do something else, even within Foo I should probably declare things and moreThings as Map, not HashMap/TreeMap:

Yes, they're the exact same object, it's about the contract you're forming with any code using it. I updated the answer a bit to clarify.

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. So if I use a Map, I can only use Map methods, but I have a HashMap underneath so any speed benefits, search benefits, etc of HashMap will be seen in the Map. And if I used a HashMap, I could use those HashMap specific methods and if I ultimately need to change the map type it's a lot more work.

so the only difference is when i pass it as a parameter for example then i need to reference one as Map<blah> and the other as HashMap<blah> but they are indeed the same exact type of object?

Note
Rectangle 27 0

dictionary What is the difference between the HashMap and Map objects in Java?


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

...

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

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

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:

You create the same maps.

Note
Rectangle 27 0

dictionary What is the difference between the HashMap and Map objects in Java?


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

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.

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

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.

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)

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.

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

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.

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.

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

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.

ah, wait, no, my Map m from above must have the methods from HashMap.

but in this example, i only get the methods from the general List class, right? regardless of whether I make it a LinkedList() or an ArrayList()? it's just that if I use insertion sort (which I imagine must be a method for List that LinkedList and ArrayList get by inheritance) it works way faster on the LinkedList?

i guess what i'm looking for is whether or not when I say Map<string, string> m = new HashMap<string, string>() my Map m can use the methods specific to HashMap, or not. I'm thinking it can't?

in addition to the perk you mentioned above, where using List means I don't need to decide which type of List I want until runtime, whereas if the interface thing didn't exist I'd have to pick one before compiling and running

so basically the only perk of using Map in the 'interface sense' is that if i have a method that requires a map, i'm guaranteeing any type of map will work in this method. but if i used a hashmap, i'm saying the method only works with hashmaps. or, put another way, my method only uses methods defined in Map class but inherited by the other Classes which extend Map.

Note
Rectangle 27 0

dictionary What is the difference between the HashMap and Map objects in Java?


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

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.

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

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.

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)

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.

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

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.

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.

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

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.

ah, wait, no, my Map m from above must have the methods from HashMap.

but in this example, i only get the methods from the general List class, right? regardless of whether I make it a LinkedList() or an ArrayList()? it's just that if I use insertion sort (which I imagine must be a method for List that LinkedList and ArrayList get by inheritance) it works way faster on the LinkedList?

i guess what i'm looking for is whether or not when I say Map<string, string> m = new HashMap<string, string>() my Map m can use the methods specific to HashMap, or not. I'm thinking it can't?

in addition to the perk you mentioned above, where using List means I don't need to decide which type of List I want until runtime, whereas if the interface thing didn't exist I'd have to pick one before compiling and running

so basically the only perk of using Map in the 'interface sense' is that if i have a method that requires a map, i'm guaranteeing any type of map will work in this method. but if i used a hashmap, i'm saying the method only works with hashmaps. or, put another way, my method only uses methods defined in Map class but inherited by the other Classes which extend Map.

Note
Rectangle 27 0

dictionary What is the difference between the HashMap and Map objects in Java?


Foo
SpecialFoo
class Foo {
    private HashMap<String, Object> things;
    private HashMap<String, Object> moreThings;

    protected HashMap<String, Object> getThings() {
        return this.things;
    }

    protected HashMap<String, Object> getMoreThings() {
        return this.moreThings;
    }

    public Foo() {
        this.things = new HashMap<String, Object>();
        this.moreThings = new HashMap<String, Object>();
    }

    // ...more...
}
class Foo {
    private Map<String, Object> things;             // <== Changed
    private Map<String, Object> moreThings;         // <== Changed

    protected Map<String, Object> getThings() {     // <== Changed
        return this.things;
    }

    protected Map<String, Object> getMoreThings() { // <== Changed
        return this.moreThings;
    }

    public Foo() {
        this.things = new HashMap<String, Object>();
        this.moreThings = new HashMap<String, Object>();
    }

    // ...more...
}
class SpecialFoo extends Foo {
    private void doSomething(Map<String, Object> t) { // <== Changed
        // ...
    }

    public void whatever() {
        this.doSomething(this.getThings());
        this.doSomething(this.getMoreThings());
    }
}

I think what he's saying is that even if you're referring to a HashMap as a Map, the implementation remains HashMap and so nothing changes about how the methods execute. If you changed the implementation behind the Map interface, properties of execution (such as speed) could indeed change.

If I had done that, then Mary would have done this:

Interfaces (and base classes) let us reveal only as much as is necessary, keeping our flexibility under the covers to make changes as appropriate. In general, we want to have our references be as basic as possible. If we don't need to know it's a HashMap, just call it a Map.

Later, I decide that actually, it's better if I use TreeMap instead of HashMap in Foo. I update Foo, changing HashMap to TreeMap. Now, SpecialFoo doesn't compile anymore, because I've broken the contract: Foo used to say it provided HashMaps, but now it's providing TreeMaps instead. So we have to fix SpecialFoo now (and this kind of thing can ripple through a codebase).

Later, Mary writes code subclassing it. She has something she needs to do with both things and moreThings, so naturally she puts that in a common method, and she uses the same type I used on getThings/getMoreThings when defining her method:

Note how I'm now using Map<String, Object> everywhere I can, only being specific when I create the actual objects.

Sometimes you can't do that, sometimes you have to be specific. But unless you have a reason to be, err toward the least-specific interface.

The advantage to using Map<String, Object> is that you can change the underlying object to be a different kind of map without breaking your contract with any code that's using it. If you declare it as HashMap<String, Object>, you have to change your contract if you want to change the underlying implementation.

The class has a couple of internal maps of string->object which it shares (via accessor methods) with subclasses. Let's say I write it with HashMaps to start with because I think that's the appropriate structure to use when writing the class.

There is no difference between the objects; you have a HashMap<String, Object> in both cases. There is a difference in the interface you have to the object. In the first case, the interface is HashMap<String, Object>, whereas in the second it's Map<String, Object>. But the underlying object is the same.

This is a great answer. It would be even better with examples.

This isn't a blind rule, but in general, coding to the most general interface is going to be less brittle than coding to something more specific. If I'd remembered that, I wouldn't have created a Foo that set Mary up for failure with SpecialFoo. If Mary had remembered that, then even though I messed up Foo, she would have declared her private method with Map instead of HashMap and my changing Foo's contract wouldn't have impacted her code.

Unless I had a really good reason for sharing that my implementation was using a HashMap (and that does happen), what I should have done was declare getThings and getMoreThings as just returning Map<String, Object> without being any more specific than that. In fact, barring a good reason to do something else, even within Foo I should probably declare things and moreThings as Map, not HashMap/TreeMap:

Yes, they're the exact same object, it's about the contract you're forming with any code using it. I updated the answer a bit to clarify.

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. So if I use a Map, I can only use Map methods, but I have a HashMap underneath so any speed benefits, search benefits, etc of HashMap will be seen in the Map. And if I used a HashMap, I could use those HashMap specific methods and if I ultimately need to change the map type it's a lot more work.

so the only difference is when i pass it as a parameter for example then i need to reference one as Map<blah> and the other as HashMap<blah> but they are indeed the same exact type of object?

Note
Rectangle 27 0

dictionary What is the difference between the HashMap and Map objects in Java?


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

Note
Rectangle 27 0

dictionary What is the difference between the HashMap and Map objects in Java?


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

...

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

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

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:

You create the same maps.

Note
Rectangle 27 0

dictionary What is the difference between the HashMap and Map objects in Java?


It is similar to how often a List is implemented as an ArrayList

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

Note
Rectangle 27 0

dictionary What is the difference between the HashMap and Map objects in Java?


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.

Note
Rectangle 27 0

dictionary What is the difference between the HashMap and Map objects in Java?


HashMap
public void HashMap getMap(){
   return map;
}
  • Method should return map key's in sorted order - Need to change return type LinkedHashMap to TreeMap.

But, If you use polymorphism feature of java, Instead of returning specific class used interface Map, It leads code reusability and less impact if any requirement change.

If your method returning Specific classes instead of Map interface you have to change return type of getMap() method each time.

Suppose you project requirement are changing each time as follows,

Note