当前位置: 首页 > 知识库问答 >
问题:

Java中HashMap和Map对象之间有什么区别?

安经纶
2023-03-14

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

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

共有3个答案

郝昊东
2023-03-14
匿名用户

Map有以下实现:

>

LinkedHashMapMap m=new LinkedHashMap()

树状图Map m=new TreeMap();

地图m=new WeakHashMap();

假设您创建了一个方法(这只是伪代码)。

public void HashMap getMap(){
   return map;
}

假设您的项目需求发生了变化:

  1. 方法应该返回map内容-需要返回HashMap。
  2. 方法应该按插入顺序返回map键-需要将返回类型HashMap更改为LinkedHashMap
  3. 方法应该按排序顺序返回map键-需要将返回类型LinkedHashMap更改为TreeMap

如果您的方法返回特定的类,而不是实现Map接口的类,则每次都必须更改getMap()方法的返回类型。

但是,如果使用Java的多态性特性,而不是返回特定的类,使用接口Map,它将提高代码的可重用性,并减少需求更改的影响。

万俟玉书
2023-03-14

Map是HashMap实现的接口,不同的是,在第二个实现中,您对HashMap的引用将只允许使用Map接口中定义的函数,而第一个实现将允许使用HashMap中的任何公共函数(包括Map接口)。

如果您阅读Sun的界面教程,可能会更有意义

巫晋鹏
2023-03-14

物体之间没有区别;你有一个HashMap

使用Map的优势

例如:假设我写了这门课:

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

这个类有几个字符串的内部映射-

后来,Mary编写了子类化代码。她需要处理事物更多事物,因此她自然地将其放在一个通用方法中,并且在定义她的方法时使用了我在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...
}

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

除非我有一个非常好的理由来分享我的实现是使用HashMap(这确实发生了),否则我应该做的是将getThingsgetMore Things声明为只是返回Map

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

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

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

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

...更改Foo不会使特别Foo停止编译。

接口(和基类)让我们只透露必要的信息,保持我们的灵活性,以进行适当的更改。总的来说,我们希望我们的引用尽可能基本。如果我们不需要知道它是一个HashMap,就称之为Map

这不是一条盲目的规则,但一般来说,对最通用的接口进行编码比对更具体的接口进行编码要不那么脆弱。如果我记得的话,我就不会创建一个Foo,用SpecialFoo设置Mary失败。如果玛丽记得,那么即使我把Foo搞砸了,她也会用Map而不是HashMap声明她的私人方法,而我更改Foo的合同也不会影响她的代码。

有时候你做不到,有时候你必须明确。但是,除非你有理由这么做,否则就要朝着最不具体的界面走。

 类似资料:
  • 问题内容: 我正在使用Eclipse来帮助我清理一些代码以正确使用Java泛型。大多数时候,它在推断类型方面做得非常出色,但是在某些情况下,推断类型必须尽可能地通用:对象。但是Eclipse似乎给了我一个选择,可以选择对象类型还是“?”类型。 那么两者之间有什么区别? 和 问题答案: 匹配项的实例,但不是。假设您要编写一个接受Strings到任何内容的映射的方法:如果您要编写 您无法提供。如果你写

  • 问题内容: 我是JSON和JavaScript对象的新手。 有人可以解释JSON和JavaScript对象之间的区别吗? 它们有什么用? 这个比那个好吗?还是取决于情况? 什么时候使用哪个,在什么情况下? 为什么首先创建JSON?它的主要目的是什么? 有人可以举例说明何时应该使用JSON而不是JavaScript对象,反之亦然吗? 问题答案: 首先,您应该知道什么是JSON: 它是与 语言无关的

  • 问题内容: 在Java 8中,和方法之间有什么区别? 问题答案: 双方map并可以应用到他们都回报。不同之处在于,该map运算为每个输入值生成一个输出值,而该运算为每个输入值生成任意数量(零个或多个)的值。 这反映在每个操作的参数中。 该map操作采用一个,对输入流中的每个值调用,并产生一个结果值,该结果值发送到输出流。 该操作采用的功能在概念上要消耗一个值并产生任意数量的值。但是,在Java中,

  • 问题内容: 后者是否仅引用由自定义构造函数创建的非原始函数对象(例如,var bird1 = new Bird();)? 问题答案: 这两个术语在ECMAScript规范中定义: 本机对象 ECMAScript实现中的对象,其语义由此规范而不是由主机环境完全定义。 注:本规范中定义了标准本机对象。一些本地对象是内置的。其他的可以在执行ECMAScript程序的过程中构造。 宿主对象 主机环境提供的

  • 当我想初始化一个HashMap时,我是Java新手。我可以找到这两个解决方案: 我知道Map是一个接口,HashMap实现了它。但为什么我们这里有两个?他们每个人都有什么好处?

  • 问题内容: 我一直在阅读《 清洁代码:敏捷软件技巧手册》 ,在第六章第95-98页中阐明了对象和数据结构之间的区别: 对象将其数据隐藏在抽象之后,并公开对该数据进行操作的函数。数据结构公开其数据,并且没有有意义的功能。 对象公开行为并隐藏数据。这使得在不更改现有行为的情况下添加新的对象变得容易。这也使得很难向现有对象添加新行为。 数据结构公开数据并且没有重大行为。这使向现有数据结构添加新行为变得容