java的map和hashmap,Java中的HashMap和Map对象有什么区别?

对象之间没有区别。有一个与您的对象的接口的差异。在第一种情况下,接口是HashMap,而在第二种情况下是Map< String,Object&gt ;.基础对象,但是,是相同的。

使用Map是你可以改变底层对象是一种不同类型的地图,而不会破坏你的合同使用它的任何代码。如果你声明它为HashMap,如果你想改变底层的实现,你必须改变你的契约。

示例:假设我写这个类:

class Foo {

private HashMap things;

private HashMap moreThings;

protected HashMap getThings() {

return this.things;

}

protected HashMap getMoreThings() {

return this.moreThings;

}

public Foo() {

this.things = new HashMap();

this.moreThings = new HashMap();

}

// ...more...

}

该类有一些内部映射的string->对象,它与(通过访问器方法)与子类共享。让我们说,我用HashMaps写它开始,因为我认为这是编写类时使用的适当的结构。

后来,玛丽写了代码子类化它。她有一些东西,她需要做的两件事情和moreThings,所以自然她提出了一个通用的方法,她使用相同的类型我使用getThings / getMoreThings定义她的方法时:

class SpecialFoo extends Foo {

private void doSomething(HashMap t) {

// ...

}

public void whatever() {

this.doSomething(this.getThings());

this.doSomething(this.getMoreThings());

}

// ...more...

}

后来,我决定,实际上,最好是如果我在Foo中使用TreeMap而不是HashMap。我更新Foo,将HashMap更改为TreeMap。现在,SpecialFoo不再编译,因为我违反了合同:Foo曾经说它提供了HashMaps,但现在它提供了TreeMaps。所以我们必须修复SpecialFoo现在(这种事情可以通过代码库)。

除非我有一个真正好的共享理由,我的实现是使用一个HashMap(并确实发生),我应该做的是声明getThings和getMoreThings作为只返回Map没有比这更具体的。事实上,除非有好的理由做别的事情,即使在Foo中我应该声明的事情和moreThings作为Map,而不是HashMap / TreeMap:

class Foo {

private Map things; // <== Changed

private Map moreThings; // <== Changed

protected Map getThings() { // <== Changed

return this.things;

}

protected Map getMoreThings() { // <== Changed

return this.moreThings;

}

public Foo() {

this.things = new HashMap();

this.moreThings = new HashMap();

}

// ...more...

}

注意我现在如何使用Map到处我可以,只有当我创建实际的对象时具体。

如果我这样做,那么玛丽会这样做:

class SpecialFoo extends Foo {

private void doSomething(Map t) { // <== Changed

// ...

}

public void whatever() {

this.doSomething(this.getThings());

this.doSomething(this.getMoreThings());

}

}

…并且更改Foo不会使SpecialFoo停止编译。

接口(和基类)让我们只显示必要的内容,保持我们的灵活性,以适当地进行更改。一般来说,我们希望我们的引用尽可能基本。如果我们不需要知道它是一个HashMap,只需将它称为一个Map。

这不是一个盲目的规则,但一般来说,编码到最通用的接口比编码到更具体的东西要脆弱。如果我记得,我不会创建一个Foo,设置玛丽的失败与SpecialFoo。如果玛丽记住了,那么即使我搞砸了Foo,她会使用Map而不是HashMap来声明它的私有方法,我改变Foo的合同不会影响她的代码。

有时你不能这样做,有时你必须具体。但除非你有理由,否则向最不具体的接口。