ЭТА ПРОБЛЕМА
В мире 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) и введите репозитории браузера . Это должно привести вас к следующему диалогу, где вы можете найти плагин:
Использовать новые плагины equals и hashCode просто, у вас будет новая опция контекстного меню equals () и hashCode (), расположенная рядом со старым. Просто нажмите ALT + INS (или CTRL + N на Mac), и вы увидите знакомое меню генерации:
Что касается toString , нам нужно только создать новый шаблон в IntelliJ. Нажмите ALT + INS и перейдите к пункту меню toString (). Нажмите на кнопку Настройки и перейдите на вкладку Шаблоны . На вкладке Шаблоны нажмите кнопку + :
Дайте новому шаблону имя (например, 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: генерируйте equals, hashCode и toString с помощью Google Guava от нашего партнера по JCG Михала Вртиака из блога vrtoonjava .