Статьи

IntelliJ IDEA: генерировать равно, hashCode и toString с Google Guava

ЭТА ПРОБЛЕМА

В мире Java нам часто нужно писать методы equals , hashCode и toString . Честно говоря, это обычно всего лишь обязательное обязательство.

Благодаря умным IDE мы обычно больше не делаем это сами. Мы просто позволяем и IDE делать тяжелую работу. Хотя есть одна проблема. Сгенерированный код обычно невероятно уродлив. Давайте рассмотрим следующие POJO:

01
02
03
04
05
06
07
08
09
10
11
12
public class Beer {
 
    private String brand;
    private String type;
    private int degrees;
    private double alcoholPercentage;
    private List<String> ingredients;
 
    // constructor
    // getters, setters if needed
 
}

ОБЫЧНОЕ РЕШЕНИЕ

Все основные IDE имеют возможность генерировать методы, которые я упоминал, но вот как будут выглядеть hashCode, equals и toString:

1. равно — длинный список утверждений IF …

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Override
public boolean equals(final Object o) {
    if (this == o) {
        return true;
    }
    if (!(o instanceof Beer)) {
        return false;
    }
 
    final Beer beer = (Beer) o;
 
    if (Double.compare(beer.alcoholPercentage, alcoholPercentage) != 0) {
        return false;
    }
    if (degrees != beer.degrees) {
        return false;
    }
    if (!brand.equals(beer.brand)) {
        return false;
    }
    if (!ingredients.equals(beer.ingredients)) {
        return false;
    }
    if (!type.equals(beer.type)) {
        return false;
    }
 
    return true;
}

2. hashCode — запутанные магические числа, xors и shift

01
02
03
04
05
06
07
08
09
10
11
12
@Override
public int hashCode() {
    int result;
    long temp;
    result = brand.hashCode();
    result = 31 * result + type.hashCode();
    result = 31 * result + degrees;
    temp = alcoholPercentage != +0.0d ? Double.doubleToLongBits(alcoholPercentage) : 0L;
    result = 31 * result + (int) (temp ^ (temp >>> 32));
    result = 31 * result + ingredients.hashCode();
    return result;
}

3. toString — неприятная конкатенация строк

01
02
03
04
05
06
07
08
09
10
@Override
public String toString() {
    return 'Beer{' +
            'brand='' + brand + '\'' +
            ', type='' + type + '\'' +
            ', degrees=' + degrees +
            ', alcoholPercentage=' + alcoholPercentage +
            ', ingredients=' + ingredients +
            '}';
}

РЕШЕНИЕ С GOOGLE GUAVA

Возможно, вы слышали о Google Guava . Может быть, вы уже используете это. В любом случае, Google Guava — это симпатичная небольшая библиотека, которая предоставляет множество полезных возможностей для Java. Используя Guava, мы можем переписать три метода выше, чтобы лучше выглядели альтернативы:

1. equals — армия операторов IF преобразована в цепной вызов

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
@Override
public boolean equals(final Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null || getClass() != obj.getClass()) {
        return false;
    }
    final Beer other = (Beer) obj;
    return Objects.equal(this.brand, other.brand) && Objects
            .equal(this.type, other.type) && Objects
            .equal(this.degrees, other.degrees) && Objects
            .equal(this.alcoholPercentage, other.alcoholPercentage) && Objects
            .equal(this.ingredients, other.ingredients);
}

2. hashCode — однострочный

1
2
3
4
@Override
public int hashCode() {
    return Objects.hashCode(brand, type, degrees, alcoholPercentage, ingredients);
}

3. toString — согласованный цепной вызов

01
02
03
04
05
06
07
08
09
10
@Override
public String toString() {
    return Objects.toStringHelper(this)
            .add('brand', brand)
            .add('type', type)
            .add('degrees', degrees)
            .add('alcoholPercentage', alcoholPercentage)
            .add('ingredients', ingredients)
            .toString();
}

УСТАНАВЛИВАЙТЕ СВОЮ ИНТЕЛЛЕЙНУЮ ИДЕЮ

Для equals и hashCode есть плагин под названием Equals и HashCode Deluxe Generator от Михала Джедынака. Вы можете установить его непосредственно в IntelliJ, просто нажмите CTRL + SHIFT + A (или CMD + SHIFT + A на Mac) и введите репозитории браузера . Это должно привести вас к следующему диалогу, где вы можете найти плагин:

Хранилище плагинов IntelliJ IDEA

Использовать новые плагины equals и hashCode просто, у вас будет новая опция контекстного меню equals () и hashCode (), расположенная рядом со старым. Просто нажмите ALT + INS (или CTRL + N на Mac), и вы увидите знакомое меню генерации:

IntelliJ IDEA Создать меню

Что касается toString , нам нужно только создать новый шаблон в IntelliJ. Нажмите ALT + INS и перейдите к пункту меню toString (). Нажмите на кнопку Настройки и перейдите на вкладку Шаблоны . На вкладке Шаблоны нажмите кнопку + :

IntelliJ IDEA шаблон строки

Дайте новому шаблону имя (например, Guava toString или около того) и вставьте следующий код в редактор:

1
2
3
4
5
6
7
8
public String toString() {
    #set ($autoImportPackages = 'com.google.common.base.Objects')
    return Objects.toStringHelper(this)
    #foreach ($member in $members)
        .add('$member.name', $member.accessor)
    #end
        .toString();
}

Использовать новый шаблон легко, просто войдите в меню генерации ( ALT + INS ), выберите toString () и обязательно выберите правильный шаблон:

Шаблон IntelliJ IDEA toString ()

Ссылка: IntelliJ IDEA: генерируйте equals, hashCode и toString с помощью Google Guava от нашего партнера по JCG Михала Вртиака из блога vrtoonjava .