【问题标题】:How to store multiple objects from a hashmap that has the same key?如何从具有相同键的哈希图中存储多个对象?
【发布时间】:2015-07-08 14:42:27
【问题描述】:

编辑

我试过这个HashMap with multiple values under the same key,我的hashMap现在看起来像这个HashMap<String, List<Place>> placeMap = new HashMap<>();

还尝试使用 Object 而不是 Place(place 是我的超类)。但是当我现在创建我的子类并想要将它们添加到 HashMap 时,我得到:

HashMap<String,List<Place>> 类型中的 put(String, List) 方法不适用于参数 (String, NamedPlace)

HashMap<String,List<Place>> 类型中的 put(String, List) 方法不适用于参数 (String, DescPlace)

这是我的添加导致错误:

NamedPlace p = new NamedPlace(x,y,answer,col,cat);
                placeMap.put(answer, p);

DescPlace dp = new DescPlace(x,y,answer, desc, col, cat);
                mp.add(dp);
                placeMap.put(answer, dp);

NamedPlace 和 DescPlace 都是 Place 的子类,我希望它们都在同一个 HashMap..

OP

我正在这里做一个小项目。问题是我需要在项目的这一部分使用 HashMap 而不是 ArrayList,因为 HashMap 的搜索速度要快得多。我已经创建了一个这样的 HashMap:

HashMap<String, Object> placeMap = new HashMap<>(); 

字符串是对象的名称,但问题是多个对象可以具有相同的名称。所以我在我的搜索字段中搜索一个对象,我想将所有具有该名称的对象存储到一个 ArrayList 中,这样我就可以只更改它们中的信息。

对象有很多不同的值,比如名称、位置、一些布尔值等。

我是否需要在我的对象类中创建一个 HashCode 方法来创建唯一的哈希码?

【问题讨论】:

  • 使用Map&lt;String, List&lt;YourObject&gt;&gt;
  • 由于地图值现在是List&lt;NamedPlace&gt;,因此您必须将setget 该类型的对象传入/传出地图。要添加NamedPlace,请检索列表(如果存在)并NamedPlace 添加到列表中
  • 您非常接近解决方案,只需将placeMap.put(answer, p); 更改为placeMap.get(answer).add(p);。确保您不会遇到地图每个条目的未初始化列表。
  • Multimap 试试这个

标签: java hashmap hashcode


【解决方案1】:

当使用标准的Map&lt;String, List&lt;YourClassHere&gt;&gt; 实例时,重要的是要记住每个条目的映射值都是List&lt;YourClassHere&gt;,并且不会以任何特殊方式处理它。所以在你的情况下,如果你有

private Map<String, List<Place>> placeMap = new HashMap<>();

然后要存储值,您需要执行以下操作:

NamedPlace p = new NamedPlace(x,y,answer,col,cat);
List<Place> list = placeMap.get (answer);
list.add(p);

但是,这段代码有一些潜在的问题。

  • 没有考虑到answer 可能不在placeMap 中。
  • 它假定您查询的每个键始终有一个 List&lt;Place&gt; 实例。

因此,解决这些潜在问题的最佳方法是执行以下操作(Java 7 及更高版本):

NamedPlace p = new NamedPlace(x,y,answer,col,cat);

if (placeMap.containsKey (answer) && placeMap.get (answer) != null) {
    placeMap.get (answer).add(p);
} else {
    List<Place> list = new ArrayList<Place> (); // ..or whatever List implementation you need
    list.add (p);
    placeMap.put (answer, list);
}

如果您想通过地点列表进行 scna,代码如下所示:

if (placeMap.containsKey (key) && placeMap.get (answer) != null) {
    for (Place p: placeMap.get (key)) {
        // Do stuff
    }
}

【讨论】:

  • 当您不使用 Java 8 的功能时,为什么要写“假设您使用的是 Java 8”(Stream API 肯定对手头的任务很有用)?相反,这是自 2004 年引入泛型以来的普通 Java 方式。
  • @SME_Dev 因为我使用了new ArrayList&lt;&gt; ()。没错,我本可以使用 Stream API,或者应该使用,但是我手动尝试了代码,而没有先在编译器中尝试,而且由于我没有完全掌握 Stream API,所以我选择不包含它。为了让 OP 也更简单,我假设他在 Java 方面没有丰富的经验。
  • 嘿,感谢 Laf 的反馈,我得到的唯一问题是行 placeMap.get(answer).list.add(p); 我收到 list cannot be resolved or is not a field 错误消息.. else 中的列表工作正常。我什至尝试将List&lt;Place&gt; list = new ArrayList&lt;Place&gt; (); 移到每个方法之外
  • @Laf new ArrayList&lt;&gt; () Java 7 引入了空菱形运算符。@Filip Blom (answer).list.add(p) 可能只是一个错字。要么在 if 语句之前声明 list,要么通过编写 placeMap.get(answer).add(p) 根本不声明变量。
  • @FilipBlom 是的,我打错了。我现在刚刚修好了。 SME_Dev:是的,它确实是在 Java 7 中引入的。但是代码示例在 Java 8 中仍然有效;)
猜你喜欢
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 2014-12-04
  • 2013-04-30
  • 2019-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多