使用HashSet时出现奇怪的行为

时间:2011-05-05 16:11:26

标签: java hashset

我正在使用HashSet来存储我编写的新类型的对象。类型定义具有以下类型:

class Node{
     Node arr[] = new Node[5];
     boolean flag = false;
}

我重写了hashCode,如下所示:

int hash = Arrays.deepHashCode(arr);
if(flag==true)
    return hash;
else
    return -hash;

和等于:

public boolean equals(Object other){
     Node t = (Node) other;
     return Arrays.deepEquals(arr, t.arr)&&(flag==t.flag);
}

我在节点中添加单词(节点是trie节点),我是按字典顺序进行的。然后我将节点存储到hashset中。奇怪的是,虽然hashset对于以一个字母开头的单词工作正常,但只要我接到下一个字母开头的单词,我的代码就会卡住。例如,对于以'a'开头的单词,一切正常,但一旦到达以'b'开头的单词,就会卡住。 “c”和“d”相同,等等。

我把它缩小到一行代码:我将节点添加到hashset的行。

由于我没有编写hashset,我不知道这里发生了什么。我确信这就是代码被卡住的地方(它不会崩溃。它似乎无限循环,但我不确定)。有谁知道发生了什么事?

- 编辑 -

后来有很多头部刮痕和许多打印声明,我已经确定我正在制作的图形实际上并不是DAG,即使它应该是,因此,deepHashCode和deepEquals函数被抛弃了。

2 个答案:

答案 0 :(得分:1)

当您不覆盖hashCode()方法时会发生什么?您是否在可能解释无限循环的节点数组中引用相同的节点,但是您应该看到一些堆栈溢出异常。尽量不要覆盖hashCode()方法,这意味着使用引用相等,是否还在发生?如果不是那么你当前的hashCode()就有问题。

答案 1 :(得分:0)

HashSet只对你的节点做两件事:调用hashCode()并使用equals()进行比较。考虑键入control-break(在windows中)或发送INT3信号(在linux中)以获取线程转储。

首先要看的是你的hashcode()和equals()方法 - 你有没有遇到无限循环的情况?