Java HashSet с использованием настраиваемого класса в качестве ключа: функция "contains ()" всегда возвращает false - PullRequest
0 голосов
/ 11 декабря 2018

Я пытаюсь использовать HashSet, используя собственный класс "Inner" в качестве типа ключа, как показано ниже:

import java.util.HashSet;
class Inner {
    int i;
    String s;
    public Inner(int i, String s) {
        this.i = i;
        this.s = s;
    }
    @Override
    public int hashCode() {
        return super.hashCode();
    }
    @Override
    public boolean equals(Object o) {
        Inner inner = (Inner) o;
        return i == inner.i && s.equals(inner.s);
    }
}

public class testEquals {
    public static void main(String [] args) {
        HashSet<Inner> hi = new HashSet<>();
        hi.add(new Inner(1,"abc"));
        System.out.println(hi.contains(new Inner(1,"abc")));
    }
}

Он печатает "false"

(1) MyВопрос в том, что пока я пытаюсь использовать функцию «содержит», мне нужно создать новый объект из класса «Внутренний» для запроса, но поскольку это новый объект, hashcode () отличается.Поэтому я всегда получаю «ложь» для «содержит» функции.

(2) Если я изменю hashCode (), чтобы он возвращал значение «истина», как равно при одинаковых значениях, тогда в других сценариях разные объектыссылки рассматриваются как "==", как одна уникальная ссылка.

(1) и (2), кажется, конфликтуют.

Как решить эту проблему?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

1) Вы должны правильно переопределить hashCode(), не нарушая контракт равных - хэш-код.

2) hashCode() не возвращает true, он возвращает значение int.Так что просто убедитесь, что он возвращает одно и то же значение int для 2 разных объектов, чьи equals() возвращают true.

0 голосов
/ 11 декабря 2018

Вы должны переопределить hashCode таким образом, чтобы два равных объекта имели одинаковый hashCode.

Например:

@Override
public int hashCode() {
    return Objects.hash(i,s);
}

Я не уверен, в чем ваша проблемас (2).Если два объекта равны согласно equals(), то HashSet должен рассматривать их как идентичные объекты, даже если они не совпадают.

Если, с другой стороны, вы хотите, чтобы HashSet рассматривал любой экземпляр Inner как уникальный (независимо от значений его переменных экземпляра), просто не переопределяйте hashCode и equals.Однако редко используется HashSet без переопределения этих методов.

...