Набор сбора Java для пользовательских типов с уникальными строками ключей - PullRequest
0 голосов
/ 15 ноября 2018

Мне было интересно, есть ли коллекция, которую я могу использовать для класса Оружия, где он похож на хэш-набор объектов Оружия, но я хочу использовать поле имени в своем классе оружия и сделать так, чтобы не было двух Оружей с одинаковым имя может существовать в наборе. Я хочу сравнить входные данные со строками моего набора оружия, чтобы увидеть, существует ли он уже, и если он есть, не помещать его в набор, но я не хочу каждый раз искать всю карту. Кроме того, это не будет чувствительно к регистру.

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Мы должны переопределить методы equals () и hashcode (), чтобы вернуть одно и то же число для имени.

Ниже приведен контракт equals () и hashcode ():

См. JavaDocjava.lang.Object

В hashCode () говорится:

Если два объекта равны в соответствии с методом equals (Object), то вызов метода hashCode для каждого из двух объектов долженвыдает тот же целочисленный результат.

Если вы переопределяете только equals (), а не hashCode (), ваш класс нарушает этот контракт.

Это также сказано в JavaDoc метода equals ():

Обратите внимание, что обычно необходимо переопределять метод hashCode всякий раз, когда этот метод переопределяется, чтобы поддерживать общий контракт для метода hashCode, в котором говорится, что равные объекты должны иметь одинаковые хеш-коды.

0 голосов
/ 15 ноября 2018

В вашем equals() проверьте только поле name на равенство.

public class Weapon {

    private String name;
    // ... other fields

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Weapon weapon = (Weapon) o;

        return name.equalsIgnoreCase(weapon.name); //case-insensitive
    }

    @Override
    public int hashCode() {
        return name.toLowerCase().hashCode();
    }
}

А затем используйте ваш HashSet следующим образом: -

public static void main(String[] args) {
    Set<Weapon> weapons = new HashSet<>();
    Weapon w1 = new Weapon();
    // TODO set the name of the weapon or pass it in constructor
    if (weapons.add(w1)) {
        System.out.println("Weapon added");
    } else {
        System.out.println("Weapon with same name already exists");
    }
}
...