【问题标题】:Cant remove custom object from HashSet无法从 HashSet 中删除自定义对象
【发布时间】:2013-09-16 08:21:47
【问题描述】:

为什么removeAll(Collection<?> a) 在集合中的对象没有被删除时返回true?我为我的自定义对象覆盖了 hashcode 和 equals 方法。 输入中的对象的哈希码与选择中对象的哈希码相同。

 private void onRemove(IStructuredSelection selection) {
            boolean removeAll = getInput().removeAll(selection.toList()); // returns true
            Set<ReadingNodeCfg> input = getInput(); // Object from selection is still there
    }

输入中的对象与选择中的对象相同,那他为什么不删除呢?

最好的问候

edit1:我通过eclipse生成equals和hashcode,getInput()返回HashSet&lt;ReadingNodeCfg&gt;,selection.toList()返回List&lt;ReadingNodeCfg&gt;

edit2

   for (Object object : selection.toList()) {
        boolean remove = getInput().remove(object); // returns false
        int hashCode = object.hashCode(); // returns 1130504316
        int hashCode2 = getInput().iterator().next().hashCode(); // returns 1130504316
        boolean equals = object.equals(getInput().iterator().next()); // returns true

    }

edit3:我现在使用的是 IObservableList。现在效果很好!

修改后输入中的哈希码发生了变化。而且我想删除的对象与修改后的输入对象具有相同的哈希码,但无论如何它没有工作,我仍然不确定为什么。

解决方案:

好吧,我现在解决了这个问题。我为遇到相同问题的任何其他人创建了一个示例。

@Test
    public void derp() {
        Person person = new Person();
        person.name = "jay";

        Set<Person> humans = new HashSet<>();
        humans.add(person);

        person.name = "fred";
        assertTrue(!humans.remove(person));
    }

person 对象在修改后无法删除。哈希集本身无法找到对象person 的哈希码。

  1. person的哈希码:1337
  2. 将其添加到 Hashcode 会在此 hashcode 和对象之间创建类似引用
  3. 更改人名将更改哈希码:1338
  4. 从哈希码中删除此对象将尝试删除哈希码为 1337 的对象,这将不起作用
  5. 如果您不覆盖 quals/hashcode,您将能够毫无问题地删除此项目

最好的问候

【问题讨论】:

  • 我认为我们需要查看您的更多代码以确定出了什么问题。 getInput 是什么,selection 会有什么价值?
  • 那么hashCode()实现正确,那么equals()呢?

标签: java equals hashcode hashset removeall


【解决方案1】:

为什么当集合内的对象没有被移除时 removeAll(Collection a) 返回 true?

仅当集合被修改时才返回 true。如果您的收藏似乎没有被修改,那么您正在寻找错误的收藏。我建议不要修改 getter 的结果(这是不好的做法),而是将任务传递给调用者。例如

boolean removeAll = removeAllFromInput(selection.toList()); // returns true

我敢打赌,getInput() 会获取该集合的防御性副本,以避免您错误地尝试更改它。

【讨论】:

  • 我现在找到了解决方案。只有当你覆盖 equals/hashcode 并且集合中的对象没有被修改时,它才会返回 true。
  • 您无法修改哈希和排序集合的键或元素应该是一个已知问题。此外,您应该将键和值与可变元素组合在一起。
【解决方案2】:

解决方案:

好吧,我现在解决了这个问题。我为遇到相同问题的任何其他人创建了一个示例。

@Test
    public void derp() {
        Person person = new Person();
        person.name = "jay";

        Set<Person> humans = new HashSet<>();
        humans.add(person);

        person.name = "fred";
        assertTrue(!humans.remove(person));
    }

修改后无法移除此 person 对象。 hashset 本身无法找到对象 person 的 hashcode。

  1. 人的哈希码:1337
  2. 将其添加到哈希码将创建 类似于此哈希码和对象之间的引用
  3. 更改人名将更改哈希码:1338
  4. 从哈希码中删除此对象将尝试删除该对象 使用哈希码 1337,这是行不通的
  5. 如果您不覆盖 equals/hashcode,您将能够删除此项目,而无需 问题

最好的问候

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-07
    • 2019-08-09
    • 1970-01-01
    • 2015-12-22
    相关资源
    最近更新 更多