将 Hashmap 与自定义内部类一起使用时出现问题

发布于 2024-11-25 21:17:54 字数 1676 浏览 0 评论 0原文

我的代码如下所示:

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 的对象多次。

I have code that looks like the following:

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); 
    }
}

The object is a private inner class (in the same class as that method) that looks like this:

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

However, despite overriding the equals and hashCode methods, the hashMap will still contain repeat keys (as in title and id are equivalent...but still show up in multiple places). I think I'm doing everything correctly, but realize I could be missing something...

Also, I know there are repeat keys because I loop through the keySet and output the results, which results in objects with the same title and id showing up multiple times.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倒数 2024-12-02 21:17:54

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

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

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

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

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

Per your comment, a HashMap cannot contain the same keys per the implementation the same key would be:

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

And since you are following the contract for equals and hashcode, any object you create here:

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

With the same id and title, will be considered the same key, and if the map previously contained a mapping for the key, the old value is replaced.

離人涙 2024-12-02 21:17:54

看起来这里一切都很好。

It looks like everything is OK here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文