为什么我的Java LinkedHashSet不删除它包含的对象?

时间:2011-10-26 02:08:08

标签: java linkedhashset

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

3 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分: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()在您插入时返回相同的值,就像您尝试删除它时一样。

答案 2 :(得分:0)

LinkedHashSet中出现错误的可能性无限小。你应该认为这是对你的问题的合理解释。

假设这是您的代码中的错误,那么可能是由于许多事情。例如:

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

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

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