2

我在 aLinkedHashSet中有一个实现equals, hashCodeand的对象compareTo(在超类中),但是当我尝试从集合中删除该确切对象时,set.remove(obj)remove 方法返回false并且该对象保留在集合中。是否LinkedHashSet应该调用equals()其对象的方法?因为它没有。这可能是一个java错误吗?我正在运行 1.6.0_25。

4

3 回答 3

5

我的猜测是您的对象的hashCode()实现返回的值与您将对象添加到集合时的值不同。

于 2011-10-26T02:13:36.093 回答
0

LinkedHashSet对我来说很好:

import java.util.*;

public class Test {
    public static void main( String[] args ) {
        LinkedHashSet<String> lhs = new LinkedHashSet<String>();
        String s = "hi";
        lhs.add( s );
        System.out.println( lhs );
        lhs.remove( s );
        System.out.println( lhs );
    }
}

也许您正在向 remove 方法传递对不同对象的引用?您确定您没有以任何方式更改参考吗?

还要确保hashCode()在插入时返回与尝试删除时相同的值。

于 2011-10-26T02:12:32.127 回答
0

这是一个错误的机会LinkedHashSet非常。您应该将此视为对您的问题的合理解释。

假设这是您的代码中的一个错误,那么它可能是由于许多原因造成的。例如:

  • 您的equalshashCode方法正在为该对象返回矛盾的答案。
  • 您的equalsorhashCode方法依赖于可变字段,并且当对象在集合中时,这些字段正在更改。(例如,如果 hashcode 值发生变化,对象很可能在错误的 hash 链上,导致remove方法找不到它。)
  • 您已将该equals方法声明为重载,而不是equals(Object). (这可以解释为什么你equals没有被调用......假设你的断言实际上是正确的。)
  • 您要删除的对象(实际上)不是您插入的对象。
  • 其他东西已经移除了该对象。
  • 您正在运行与您正在检查的源代码不匹配的某个类的不同版本。

现在,我知道您已经驳回了其中一些解释。但这可能为时过早。审查您基于该解雇的证据。

您可以使用的另一种方法是使用 Java 调试器来取证检查数据结构(例如 的内部结构LinkedHashSet)并单步执行应该发生删除的代码。

于 2011-10-26T02:32:03.357 回答