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

hashSet.contains(object)对于插入后修改的实例返回false

胡和煦
2023-03-14

根据java.util.hashset.contains()的JavaDoc,该方法执行以下操作

但是,这似乎不适用于以下代码

public static void main(String[] args) {
    HashSet<DemoClass> set = new HashSet<DemoClass>();
    DemoClass toInsert = new DemoClass();
    toInsert.v1 = "test1";
    toInsert.v2 = "test2";
    set.add(toInsert);
    toInsert.v1 = null;

    DemoClass toCheck = new DemoClass();
    toCheck.v1 = null;
    toCheck.v2 = "test2";

    System.out.println(set.contains(toCheck));
    System.out.println(toCheck.equals(toInsert));
}

private static class DemoClass {
    String v1;
    String v2;

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((v1 == null) ? 0 : v1.hashCode());
        result = prime * result + ((v2 == null) ? 0 : v2.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        DemoClass other = (DemoClass) obj;
        if (v1 == null) {
            if (other.v1 != null)
                return false;
        } else if (!v1.equals(other.v1))
            return false;
        if (v2 == null) {
            if (other.v2 != null)
                return false;
        } else if (!v2.equals(other.v2))
            return false;
        return true;
    }

}

打印出来:

共有1个答案

吴伟志
2023-03-14

当一个对象存储在hashset中时,它被放入一个数据结构中,该数据结构可以被对象的hashcode()轻松(读取:有效)搜索。修改对象可能会更改它的hashCode()(这取决于您实现它的方式),但不会更新它在hashSet中的位置,因为对象无法知道它包含在其中。

您可以在这里做几件事:

>

  • 修改hashcode()的实现,使其不受您要更改的字段的影响。假设该字段对对象的状态很重要,并且参与了equals(Object)方法,那么这就有点带有代码味道,应该避免。

    在修改对象之前,请将其从集合中删除,然后在修改完成后重新添加:


    Set<DemoClass> mySet = ...;
    DemoClass demo = ...;
    boolean wasInSet = mySet.remove(demo);
    demo.setV1("new v1");
    demo.setV2("new v2");
    if (wasInSet) {
        set.add(demo);
    }
    

  •  类似资料:
    • 我一直在研究猫鼬文档,但我找不到一种方法来实现我想要做的事情。考虑一个MangGDB用户集合。还可以考虑一个包含DB集合中所有字段的蒙古人用户模式。 现在,我想登录到控制台,所有用户,但属性已更改。有点像: 用户。图例(): 给定的异步类型。find()函数我不确定这是否可以实现。我来自C#和PHP背景,只处理关系数据库,这可以通过在用户类中使用只返回所需值的函数轻松实现。 能做到吗?!

    • 问题内容: 我正在尝试在INSERT语句之后找回键值。示例:我有一个带有属性名称和ID的表。id是一个生成的值。 现在,我想在同一步骤中重新获得ID。这是怎么做的? 我们正在使用Microsoft SQL Server 2008。 问题答案: 无需单独的SELECT … 这也适用于非IDENTITY列(例如GUID)

    • 问题内容: 我正在尝试从指定的URL返回JSON数据,但是当警报弹出时,它仅显示[object Object](我意识到object对象实际上不是错误)。 我想在警报中吐出职位名称和其他字段 。我该怎么做呢? 这是我正在查看的JSON示例(完整文件包含大约30个帖子) 这是我正在使用的脚本。 任何帮助深表感谢。 问题答案: 试试这个:

    • 本文向大家介绍Mybatis批量插入返回成功的数目实例,包括了Mybatis批量插入返回成功的数目实例的使用技巧和注意事项,需要的朋友参考一下 Mybatis批量插入返回影响的行数 环境: postgresql 9.6.5 spring 4.1 mybatis3 junit4 log4j ThesisMapper.xml: Mapper.java 借口: 服务类: ThesisService: 测

    • 问题内容: 如果一个方法填充/修改了一个对象,是否最好返回该对象或将返回类型保持为空,并且该方法将通过其引用来修改该对象? 我知道这是一个琐碎的问题,但是哪个是最优选的? 问题答案: 我取决于您的样式,但是返回的优点之一是:您可以调用,即可以链接方法调用。 例如,看看这是怎么做的,它允许这样的事情

    • 我想使用Drools规则进行一些验证: 我第一次创建了一个Statefull-KieSession,它第一次按预期工作。然而,当我重新运行该规则时,验证事实仍在内存中,这不是我想要的。因此,我尝试将示例调整为无状态KieSession。 使用KieSession K会话: 使用无状态KieSession会话: statefull会话在validations集合中返回一个Validation对象,无