gpt4 book ai didi

java - Java 中的 HashMap 和 Map 对象有什么区别?

转载 作者:太空宇宙 更新时间:2023-11-04 10:29:50 24 4
gpt4 key购买 nike

我创建的以下 map 之间有什么区别(在另一个问题中,人们似乎可以互换使用它们来回答,我想知道它们是否/如何不同):

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

最佳答案

对象之间没有区别;你有一个HashMap<String, Object>在这两种情况下。对象的界面有所不同。第一种情况,接口(interface)是HashMap<String, Object> ,而第二个是 Map<String, Object> 。但底层对象是相同的。

使用 Map<String, Object> 的优势是您可以将底层对象更改为不同类型的映射,而不会破坏与使用它的任何代码的约定。如果您将其声明为 HashMap<String, Object> ,如果你想改变底层的实现,你就必须改变你的合约。

<小时/>

示例:假设我编写这个类:

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

该类有几个字符串->对象的内部映射,它与子类共享(通过访问器方法)。假设我用 HashMap 写它首先是因为我认为这是编写类时使用的合适结构。

后来,玛丽编写了子类化它的代码。她有一些事情需要与两者一起做thingsmoreThings ,所以很自然地她将其放入一个通用方法中,并且她使用了我在 getThings 上使用的相同类型。/getMoreThings定义她的方法时:

class SpecialFoo extends Foo {
private void doSomething(HashMap<String, Object> t) {
// ...
}

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

// ...more...
}

后来我决定,其实我用TreeMap会更好。而不是HashMapFoo 。我更新Foo ,改变HashMapTreeMap 。现在,SpecialFoo不再编译,因为我违反了契约(Contract):Foo过去常说它提供了HashMap s,但现在它提供 TreeMaps反而。所以我们必须修复SpecialFoo现在(这种事情可能会影响代码库)。

除非我有充分的理由分享我的实现是使用 HashMap (这确实发生了),我应该做的是声明 getThingsgetMoreThings刚回来Map<String, Object>没有比这更具体的了。事实上,除非有充分的理由去做其他事情,即使在 Foo 范围内也是如此。我可能应该声明 thingsmoreThingsMap ,不是HashMap/TreeMap :

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

注意我现在如何使用 Map<String, Object>尽我所能,只有在创建实际对象时才具体。

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

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

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

...并改变Foo不会做SpecialFoo停止编译。

接口(interface)(和基类)让我们仅展示必要的内容,从而保持我们的灵 active 以进行适当的更改。一般来说,我们希望我们的引用文献尽可能基本。如果我们不需要知道它是 HashMap ,就叫它 Map .

这不是一个盲目的规则,但总的来说,对最通用的接口(interface)进行编码比对更具体的东西进行编码要更容易。如果我记得这一点,我就不会创建 Foo这让玛丽注定失败 SpecialFoo 。如果玛丽记得这一点,那么即使我搞砸了Foo ,她会用 Map 声明她的私有(private)方法。而不是HashMap和我的改变Foo的契约(Contract)不会影响她的代码。

有时你不能这样做,有时你必须具体。但除非你有理由这样做,否则最好选择最不具体的界面。

关于java - Java 中的 HashMap 和 Map 对象有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50139266/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com