То, как делает ArrayList, содержит (), метод оценивает объекты?

Скажите, что я создаю один объект и добавляю его к моему ArrayList. Если я затем создаю другой объект с точно тем же входом конструктора, будет contains() метод оценивает два объекта быть тем же? Предположите, что конструктор не делает ничего забавного с входом, и переменные, сохраненные в обоих объектах, идентичны.

ArrayList<Thing> basket = new ArrayList<Thing>();  
Thing thing = new Thing(100);  
basket.add(thing);  
Thing another = new Thing(100);  
basket.contains(another); // true or false?

class Thing {  
    public int value;  

    public Thing (int x) {
        value = x;
    }

    equals (Thing x) {
        if (x.value == value) return true;
        return false;
    }
}

Это как class должен быть реализован, чтобы иметь contains() вернуть true?

292
задан Bakuriu 23 April 2014 в 21:17
поделиться

5 ответов

ArrayList реализует интерфейс списка.

Если вы посмотрите на Javadoc для List в методе contains , то увидите, что он использует метод equals () для оценки того, два объекта одинаковы.

328
ответ дан 23 November 2019 в 01:40
поделиться

Он использует метод equals для объектов. Таким образом, если Thing не переопределит равенство и не использует переменные, хранящиеся в объектах для сравнения, он не вернет истину в методе contains () .

7
ответ дан 23 November 2019 в 01:40
поделиться

Как правило, вы также должны переопределять hashCode () каждый раз, когда вы переопределяете equals () , даже если только для повышения производительности. HashCode () решает, в какую «корзину» сортируется ваш объект при сравнении, поэтому любые два объекта, которые equal () оцениваются как истинные, должны возвращать один и тот же hashCode значение () . Я не могу вспомнить поведение по умолчанию hashCode () (если он возвращает 0, тогда ваш код должен работать, но медленно, но если он возвращает адрес, ваш код не сработает). Я действительно помню много раз, когда мой код терпел неудачу, потому что я забыл переопределить hashCode () . :)

12
ответ дан 23 November 2019 в 01:40
поделиться

ArrayList использует метод equals, реализованный в классе (в вашем случае класс Thing), для сравнения равенства.

15
ответ дан 23 November 2019 в 01:40
поделиться

Другие авторы посвящены вопросу о том, как работает contains ().

Не менее важный аспект вашего вопроса - как правильно реализовать equals (). И ответ на этот вопрос действительно зависит от того, что составляет объектное равенство для этого конкретного класса. В приведенном вами примере, если у вас есть два разных объекта с x = 5, равны ли они? Это действительно зависит от того, что вы пытаетесь сделать.

Если вас интересует только равенство объектов, то реализация по умолчанию .equals () (предоставляемая Object) использует только идентичность (т.е. this == other). Если это то, что вы хотите, просто не реализуйте equals () в своем классе (пусть он наследуется от Object). Код, который вы написали, хотя и является правильным, если вы собираетесь использовать идентификацию, никогда не появится в реальном классе b / c, он не дает никаких преимуществ по сравнению с использованием реализации Object.equals () по умолчанию.

Если вы только начинаете заниматься этим, я настоятельно рекомендую книгу Джошуа Блоха «Эффективная Java». Это отличное чтение, и оно охватывает такого рода вещи (плюс то, как правильно реализовать equals (), когда вы пытаетесь сделать больше, чем сравнения на основе идентичности)

4
ответ дан 23 November 2019 в 01:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: