I am having trouble with HashSets. My program performs a Breadth First Search and I made a hashset to keep track of visited states. States are represented by int[]
array. However, HashSet's contains method does not seem to be working as expected. Basically, it is not filtering out int[]
arrays that should already have been added.
Here are the relevant parts of my code:
private boolean notVisitedAndNotNull(PuzzleState nextPS) {
if (nextPS != null && !this.visited.contains(nextPS.getStateArray))
return true;
return false;
}
private void addToQueue(PuzzleState nextPS) {
if (notVisitedAndNotNull(nextPS))
queue.add(nextPS);
}
private boolean solveByBFS() {
queue.clear();
queue.add(this.initialState);
long startTime = System.currentTimeMillis();
while(!queue.isEmpty()) {
if (queue.size() > maxQueueSize)
maxQueueSize = queue.size();
this.currentState = queue.poll();
if (this.currentState.equals(finalState)) {
System.out.println("Successful! Ending Time: " + startTime);
return true;
}
visited.add(this.currentState.getStateArray()); //this adds int[] array
this.addToQueue(this.currentState.moveUp());
this.addToQueue(this.currentState.moveDown());
this.addToQueue(this.currentState.moveRight());
this.addToQueue(this.currentState.moveLeft());
}
return false;
}
I apologize for posting so much code. I searched a bit and it seems that in order for HashSet to work correctly, I would have to implement hashCode
and equals
of HashSet
. I'm not sure if this is possible for an int[]
array. Is it better to just use a HashMap
then and use toString
method on int[]
array to serve as a key?
Ok, I got this working now. Here is the code I added if anyone is interested:
@Override
public boolean equals(Object o) {
if (o instanceof PuzzleState) {
return (Arrays.equals(((PuzzleState) o).getStateArray(), this.getStateArray()));
}
return false;
}
@Override
public int hashCode() {
return Arrays.hashCode(this.getStateArray());
}