【问题标题】:Problem with using a Hashmap with a custom inner class使用带有自定义内部类的 Hashmap 的问题
【发布时间】:2011-07-22 17:13:47
【问题描述】:

我的代码如下所示:

private void MethodToDo(SpecialObject o) {
    Map<InfoObj, Integer> totalNeeds = new HashMap<InfoObj, Integer>();

    for (ListObject obj : o.getListOfObjects()) {
        InfoObj infoObj = new InfoObj(obj.getTitle(), obj.getId());
        Integer need = totalNeeds.get(infoObj);

        if (need == null) {
           need = new Integer(obj.getNeeded());
        } else {
           need = need + obj.getNeeded();
        }
        totalNeeds.put(infoObj, need); 
    }
}

该对象是一个私有内部类(与该方法在同一类中),如下所示:

private class InfoObj {
    private String  title;
    private Integer id;

    public InfoObj(String title, Integer id) {
        this.title = title;
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public Integer getId() {
        return id;
    }

    @Override 
    public boolean equals(Object io2) {
        if (this == io2) { return true; }
        if ( !(io2 instanceof InfoObj) ) { return false; }
        InfoObj temp = (InfoObj) io2;
        return this.id.equals(temp.id) && this.title.equals(temp.title);
    }

    @Override
    public int hashCode() {
        final int prime = 7;
        int result = 1;
        result = prime * result
                + ((this.title == null) ? 0 : this.title.hashCode());
        result = prime * result
                + ((this.id == null) ? 0 : this.id.hashCode());
        return result;
    }

然而,尽管重写了 equals 和 hashCode 方法,hashMap 仍将包含重复键(如在 title 和 id 中是等价的......但仍会出现在多个位置)。我认为我做的一切都是正确的,但意识到我可能会遗漏一些东西......

另外,我知道有重复键,因为我循环遍历 keySet 并输出结果,这导致具有相同标题和 id 的对象多次出现。

【问题讨论】:

  • repeat results是指重复键还是重复值?
  • 您是否有显示重复键的 SSCCE?你确定有重复吗?
  • 不要相信这与 InfoObj 的内在有关。你的 hashCode() 被调用了吗?
  • 表示重复键。我得到了重复键的显示。
  • 所以java.util.HashMap.keySet() 多次返回给定键?假设密钥由InfoObjidtitle 属性的实例标识。

标签: java hashmap


【解决方案1】:

根据您的评论,HashMap 不能在每个实现中包含相同的键,相同的键将是:

(e.hash == hash && ((k = e.key) == key || key.equals(k)))

由于您遵循 equals 和 hashcode 的约定,因此您在此处创建的任何对象:

InfoObj infoObj = new InfoObj(obj.getTitle(), obj.getId());

具有相同的 id 和标题,将被视为相同的 key,如果映射先前包含键的映射,则替换旧值。

【讨论】:

  • 我相信我说错了。键在重复,这会造成混乱。好像用于键的对象不一样。
  • @Unknown 如果键重复,则先前的值将被新的键值替换,键相等确实由您覆盖 equals 方法确定。因此,您创建的任何具有相同 id 和标题的对象都将替换 HashMap 上的先前值。
  • @OscarMk 这正是他想要的,但显然重复的键确实出现了。 equalshashCode 方法看起来没问题,所以这很奇怪。不知道,能举个例子吗?也许从带有重复键的 HashMap 的条目列表中粘贴一些输出。
  • @G_H 那么代码没有问题,必须是代码中没有的其他内容。
  • 我仔细检查了输出...并且输出在错误的位置。进一步的代码检查表明代码很好,但输出令人困惑且不正确。感谢您的帮助。
【解决方案2】:

这里看起来一切正常。

【讨论】:

    猜你喜欢
    • 2012-07-09
    • 1970-01-01
    • 2020-03-25
    • 1970-01-01
    • 2012-12-07
    • 2010-11-25
    • 1970-01-01
    • 2011-07-22
    • 1970-01-01
    相关资源
    最近更新 更多