Dies ist der Artikel am 18. Tag von Kotlin Adventskalender 2017 (Veröffentlichung verzögert sich, Sumimasen: bow :)
Wenn Sie Kotlin aus der Perspektive von Effective Java betrachten, ein Muss für Java-Ingenieure, können Sie sehen, dass Kotlin sehr geschickt ist.
Schauen wir uns hier die Überschreibung von "equals" und "hashCode" der Elemente 8 und 9 von Effective Java Kapitel 3 an.
equals
und hashCode
Sehen wir uns die Punkte 8 und 9 von Effective Java Kapitel 3 an. Ungefähr das Folgende ist geschrieben.
x
vs. x.equals (null)
is false
* Wenn Sie weitere Details erfahren möchten, können Sie Informationen über Google finden. Versuchen Sie: Bogen:equals
überschreiben, müssen Sie auch hashCode
überschreibenAls ich es in Java implementiert habe, habe ich es wie folgt implementiert.
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;
}
}
Übrigens wurden "equals" und "hashCode" automatisch von IntelliJ generiert.
Übrigens, wenn es eine Änderung gibt, wie das Hinzufügen eines Feldes zur Klasse danach, können diese "gleich" und "hashCode" weiterhin die ursprünglich erwarteten Spezifikationen erfüllen? Es liegt am Implementierer und es ist ein Teil, den Sie bewusst schützen müssen: cry:
Was ist, wenn dies Kotlin ist?
data class DataB(
val a: String,
val b: String,
val c: String?
)
Wenn Sie die Ihnen bekannte Datenklasse verwenden, ist dies in Ordnung: Lachen:
Lassen Sie uns dies dekompilieren.
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;
}
}
}
Sie haben "equals" und "hashCode" ordnungsgemäß erstellt. Und es scheint sich genauso zu verhalten wie der automatisch generierte Code in Java. .. .. Vielleicht. (Nicht bestätigt (´-`) .. oO (hashCode, NonNull-Feld wird ebenfalls auf null geprüft)
Auf diese Weise implementiert Kotlins "Datenklasse" automatisch "gleich" und "Hashcode", sodass es einfach erscheint, die ursprünglichen Spezifikationen beizubehalten, selbst wenn Sie Änderungen an der Klasse vornehmen.
Durch Überschreiben von equals
und hashCode
fühlt es sich gut an, Lombok zu verwenden: heat_smile:
(Es könnte interessant sein, die Funktionen von Lombok mit Kotlin zu vergleichen?)
Dieses Mal hatten wir nur "equals" und "hashCode", aber Kotlin hat immer noch einige sehr nützliche Funktionen zum Üben von Effective Java. Es kann interessant sein, einen Blick auf Kotlins Sprachfunktionen im Vergleich zu Effective Java zu werfen, da Sie sehen können, dass es ziemlich geschickt ist.
Übrigens, Effective Java wurde vor einiger Zeit veröffentlicht und es gibt einige alte Teile, aber wenn Sie interessiert sind, kommen Sie bitte und sehen Sie sich die 3. Ausgabe in Kürze an! 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