This is the article on the 18th day of Kotlin Advent Calendar 2017.
If you look at Kotlin from the perspective of [Effective Java](Effective Java), a must-read for Java engineers, you can see that Kotlin is very nifty.
Here, let's take a look at the Override of ʻequals and
hashCode` of items 8 and 9 of Effective Java Chapter 3.
and
hashCode`Let's review items 8 and 9 of Effective Java Chapter 3. Roughly the following is written.
method must meet the following general contract --Reflexive, contrasting, transitive, consistent, non-null
x vs.
x.equals (null) is
false` * If you want to know more details, go to Google and you will find information. Try: bow:, you also need to override
hashCode`When I implemented it in Java, I implemented it as follows.
public class DataA {
@NotNull
private final String a;
@NotNull
private final String b;
@Nullable
private final String c;
public DataA(@NotNull String a, @NotNull String b, @Nullable String c) {
this.a = a;
this.b = b;
this.c = c;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DataA dataA = (DataA) o;
if (!a.equals(dataA.a)) return false;
if (!b.equals(dataA.b)) return false;
return c != null ? c.equals(dataA.c) : dataA.c == null;
}
@Override
public int hashCode() {
int result = a.hashCode();
result = 31 * result + b.hashCode();
result = 31 * result + (c != null ? c.hashCode() : 0);
return result;
}
}
By the way, ʻequalsand
hashCode` were automatically generated by IntelliJ.
By the way, if there is a change such as adding a field to the class after this, can these ʻequalsand
hashCode` continue to meet the specifications originally expected?
It's up to the implementer, and it's a part that you have to consciously protect: cry:
What if this is Kotlin?
data class DataB(
val a: String,
val b: String,
val c: String?
)
If you use the data class
you know, it's OK: laughing:
Let's decompile this.
public final class DataB {
@NotNull
private final String a;
@NotNull
private final String b;
@Nullable
private final String c;
...
public int hashCode() {
return ((this.a != null ? this.a.hashCode() : 0) * 31 + (this.b != null ? this.b.hashCode() : 0)) * 31 + (this.c != null ? this.c.hashCode() : 0);
}
public boolean equals(Object var1) {
if (this != var1) {
if (var1 instanceof DataB) {
DataB var2 = (DataB)var1;
if (Intrinsics.areEqual(this.a, var2.a) && Intrinsics.areEqual(this.b, var2.b) && Intrinsics.areEqual(this.c, var2.c)) {
return true;
}
}
return false;
} else {
return true;
}
}
}
You have ʻequals and
hashCode properly. And it seems to behave in the same way as the auto-generated code in Java. .. .. Perhaps. (Not confirmed (´-
) .. oO (hashCode, NonNull field is also null checked)
In this way, Kotlin's data class
automatically implements ʻequals and
hashCode`, so it seems easy to keep the original specifications even if you make changes to the class.
ʻEquals and
hashCode` Override makes it feel good to use Lombok: sweat_smile:
(It might be interesting to compare the features of Lombok with Kotlin?)
This time we only had ʻequals and
hashCode`, but Kotlin still has some very useful features for practicing Effective Java.
It may be interesting to take a look at Kotlin's language features compared to Effective Java, as you can see that it's pretty nifty.
By the way, Effective Java was published quite a while ago and there are some old parts, but if you are interested, please come and see the 3rd edition coming soon! https://www.amazon.co.jp/Effective-Java-3rd-Joshua-Bloch/dp/0134685997
https://www.amazon.co.jp/EFFECTIVE-JAVA-Java-Joshua-Bloch/dp/4621066056/ref=pd_lpo_sbs_14_t_0?_encoding=UTF8&psc=1&refRID=VF4RXTQQV4QXR9KD78S0
Recommended Posts