Java - метод HashSet contains () не работает?

У меня проблемы с HashSets. Моя программа выполняет поиск в ширину, и я создал набор хэшей для отслеживания посещенных состояний. Состояния представлены массивом int[]. Однако метод contains в HashSet, похоже, не работает должным образом. По сути, это не фильтрация int[] массивов, которые уже должны были быть добавлены.

Вот соответствующие части моего кода:

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;
}

Прошу прощения за публикацию такого большого количества кода. Я немного поискал, и кажется, что для корректной работы HashSet мне пришлось бы реализовать hashCode и equals из HashSet. Я не уверен, что это возможно для массива int[]. Не лучше ли просто использовать HashMap, а затем использовать метод toString для массива int[] в качестве ключа?

Хорошо, я получил это работает сейчас. Вот код, который я добавил, если кому-то интересно:

@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());
}

person mrQWERTY    schedule 12.09.2014    source источник
comment
Изменили ли вы методы PuzzleState equals и/или hashCode, если да, то как...?   -  person MadProgrammer    schedule 12.09.2014
comment
@MadProgrammer Я делаю это прямо сейчас. Теперь я понимаю проблему. Спасибо   -  person mrQWERTY    schedule 12.09.2014
comment
Также мне придется переопределить оба? Или мне просто нужно переопределить один? Например, я не считаю необходимым переопределять «hashCode», но необходимо переопределять «равно».   -  person mrQWERTY    schedule 12.09.2014
comment
Да. Существует договорное требование между hashCode и equals   -  person MadProgrammer    schedule 12.09.2014


Ответы (1)


Равенство массивов осуществляется только по ссылке. Вы спрашиваете, содержит ли набор точно такой же объект массива, он не проверяет содержимое массива, чтобы увидеть, существует ли "похожий" массив.

Связанный:

person William Price    schedule 12.09.2014
comment
Интересно, потому что, если я создам Class и переопределю его equals и hashCode, я могу добавить один экземпляр Class к HashSet и использовать другой экземпляр в contains, и он вернет true... - person MadProgrammer; 12.09.2014
comment
Да, но int[] в Java не реализует equals и hashCode таким образом, чтобы они работали как таковые. Из кода OP: visited.add(this.currentState.getStateArray()); //this adds int[] array - person William Price; 12.09.2014