Статьи

NetBeans в классе: обязательные методы для бобов (часть 2)


колледже Доусон в Монреале, Канада. Он также является программным консультантом и по совместительству преподавателем в Школе расширенного обучения при Институте вычислительной техники Университета Конкордия . Он ведет блог на omniprogrammer.com и пишет в Твиттере @omniprof . Его регулярные колонки о NetBeans в образовании перечислены здесь .

В следующей статье о бинах и новичках, начиная с части 1 , я представлю еще три обязательных метода. Первые два являются методами, которые мы переопределяем из суперкласса Object, и они равны и hashCode . Последнее требует, чтобы был добавлен интерфейс Comparable, а метод — CompareTo .

equals () и hashCode ()

Эти два метода идут вместе, как рыба и чипсы. По этой причине, когда в IDE NetBeans вы выбираете «Источник | Вставить код», они отображаются вместе:

Цель метода equals состоит в том, чтобы определить, находится ли экземпляр объекта, вызывающего метод, в том же состоянии, что и объекты того же типа, которые переданы ему. Помните, что использование оператора равенства ‘==’ сравнивает адреса, хранящиеся в ссылках объекта, а не в состоянии. Метод equals не должен сравнивать состояние каждого члена класса. Вы решаете, что значит быть равным.

Например, если у бина есть ключ, например, когда бин загружается из записи в базе данных, то единственный ключ, который нужно учитывать, — это ключ. Две записи с одинаковым первичным ключом одинаковы. С другой стороны, для компонента без гарантированного уникального ключа может потребоваться сравнить состояние каждого члена на равенство. Это также подразумевает, что каждый член бина, который сам является объектом, должен иметь метод equals .

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

Ключом к пониманию хеш-кода является знание того, что если два объекта одного типа не имеют одинаковый хеш-код, они не могут быть равны. Это важно, если учесть, что нашим лучшим другом в коде является целое число. Больше чем любой другой тип данных мы любим целые числа, потому что наш процессор живет для целых чисел. Целые числа обрабатываются быстрее, чем любой другой тип. Чтобы сравнить две строки, нам нужно обработать каждый символ в каждой строке. Если мы сравнили хеш-код каждой строки, и они не были одинаковыми, то нет никакой необходимости в дальнейшей работе.

Только если хеш-коды одинаковы, нам нужно вызывать метод equals . Вот почему два всегда идут вместе. Еще одна важная цель хэш-кода и создания пар равных — это хэш-коллекции, почти всегда ваш первый выбор для использования коллекций.

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

Для этого примера я выбрал несколько участников.

Вот код, который создается NetBeans.

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 13 * hash + Objects.hashCode(this.manufacturer);
        hash = 13 * hash + Objects.hashCode(this.model);
        hash = 13 * hash + this.engineDisplacement;
        hash = 13 * hash + this.cylinders;
        hash = 13 * hash + Objects.hashCode(this.transmission);
        hash = 13 * hash + Objects.hashCode(this.driveTrain);
        hash = 13 * hash + this.weight;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final MyCarBean other = (MyCarBean) obj;
        if (!Objects.equals(this.manufacturer, other.manufacturer)) {
            return false;
        }
        if (!Objects.equals(this.model, other.model)) {
            return false;
        }
        if (this.engineDisplacement != other.engineDisplacement) {
            return false;
        }
        if (this.cylinders != other.cylinders) {
            return false;
        }
        if (!Objects.equals(this.transmission, other.transmission)) {
            return false;
        }
        if (!Objects.equals(this.driveTrain, other.driveTrain)) {
            return false;
        }
        if (this.weight != other.weight) {
            return false;
        }
        return true;
    }

Изучение кода, сгенерированного NetBeans, — это хороший способ узнать больше о кодировании. Обратите внимание на использование статических методов класса Objects (да, в конце есть ‘s’). Этот класс был добавлен в Java 7 и решает проблему нулевых ссылок. Что если строка в одном объекте не была инициализирована? Если вы вызываете его методы equals или hashcode, вы получите исключение Null Pointer .

Сопоставимый интерфейс и сравнить с ()

Последний метод, который я считаю обязательным, это сравнение . Задача этого метода — определить, является ли вызывающий его объект меньше, равен или больше объекта того же типа, который ему передан. В отличие от equals нет оптимизации хеш-кода. Вы должны решить, что составляет эти три условия, и вернуть их как меньше нуля, нуля или больше нуля, как правило, -1, 0 или 1.

Для этого метода есть только минимальная помощь от NetBeans. Вы в значительной степени самостоятельно. Первый шаг — добавить интерфейс Comparable к классу.

public class MyCarBean implements Comparable
 
  {
 

Обратите внимание на использование обобщений, чтобы гарантировать, что только объекты типа MyCarBean могут использоваться в сравнении. Будьте осторожны с тем фактом, что это будет просто проверка во время компиляции, а не проверка во время выполнения.

При добавлении этого кода NetBeans объявляет ошибку, а указание на лампочку показывает, что это такое.

Нажатие на лампочку дает два варианта.

Выберите первый, реализуйте все абстрактные методы, и следующий код будет добавлен в класс.

    @Override
    public int compareTo(MyCarBean o) {
        throw new UnsupportedOperationException("Not supported yet."); 
    }

В следующей статье мы рассмотрим, как написать метод CompareTo !