0

I'm using a HashSet to store objects of a new type that I wrote. The type definition is of the following sort:

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

I rewrote hashCode as follows:

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

and equals:

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

I'm adding words into the nodes (the nodes are trie nodes) and I'm doing so in dictionary order. I'm then storing the nodes into the hashset. The strange thing is that while the hashset works fine for words beginning with one letter, as soon as I get to words beginning with the next letter, my code gets stuck. For example, everything works fine for words beginning with 'a', but as soon as it gets to words beginning with 'b', it gets stuck. Same for 'c' and 'd' and so on.

I narrowed it down to one line of code: the line where I'm adding the node to the hashset.

Since I didn't write the hashset, I don't know what's going on here. I'm sure that that's where the code gets stuck (it doesn't crash. It seems to loop infinitely, but I'm not sure). Does anyone know what's going on?

--Edit--

Lots of head scratching and many print statements later, I have determined that the graph I was making was not actually a DAG, even though it should be and therefore, the deepHashCode and deepEquals functions were being thrown off.

efficiencyIsBliss
  • 3,043
  • 7
  • 38
  • 44
  • 1
    You have to implement equals() as well. Can you post your equals code? You can find the code for HashSet in the JDK and step into it using your debugger (next to Run in your IDE). – Peter Lawrey May 05 '11 at 16:15
  • 1
    What do you mean by "stuck"? Does your code simply hang there (seemingly in an endless loop)? If so, check if you have a `Node` that references itself in `arr`. That would probably cause `deepHashCode()` to recurse endlessly. – Joachim Sauer May 05 '11 at 16:15
  • Did you implement the hashCode() function on Node? – JustinKSU May 05 '11 at 16:15
  • While equals is important for correctness, not implementing equals would reduce the likelihood of the HashSet.add(...) getting 'stuck'. – Dilum Ranatunga May 05 '11 at 16:17
  • Is it possible that there is a cyclic dependency somewhere? How do you put your nodes into the array of another node? – Omnaest May 05 '11 at 16:19
  • Note: The hashcode is computed when a item is added to a hashset, or when you test whether the hashset contains a particular item. If you change the item after it has been added to the hashset, the hashcode is not recalculated. – Devon_C_Miller May 05 '11 at 16:22
  • The deepHashCode should not recurse endlessly, since Node is a node of a DAG. I implemented equals as well. Updated the question to show the code for that. – efficiencyIsBliss May 05 '11 at 17:18

2 Answers2

1

What happens when you don't override the hashCode() method? Are you referencing the same Node within your arrays of nodes that may explain the infinite loop but then you should see some stack overflow exceptions. Try to not to override the hashCode() method meaning using reference equality, is it still happening? If it is not then there something wrong in your current hashCode().

Y G
  • 68
  • 1
  • 6
0

HashSet will do only two things with your nodes: call hashCode() and compare them using equals(). Consider typing control-break (in windows) or sending an INT3 signal (in linux) to get the thread dump.

The first place to look is in your hashcode() and equals() methods -- do you have a case where you hit an infinite loop?

Dilum Ranatunga
  • 13,254
  • 3
  • 41
  • 52