Take a look at Kotlin from an Effective Java perspective

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.

Override of ʻequalsandhashCode`

Overview

Let's review items 8 and 9 of Effective Java Chapter 3. Roughly the following is written.

  1. Override ʻequals` if you want the class to have the concept of logical equivalence.
  2. The ʻequalsmethod must meet the following general contract --Reflexive, contrasting, transitive, consistent, non-nullx vs. x.equals (null) is false` * If you want to know more details, go to Google and you will find information. Try: bow:
  3. If you override ʻequals, you also need to override hashCode`

Try to implement in Java

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, ʻequalsandhashCode` 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 ʻequalsandhashCode` 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:

Try to implement with Kotlin

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.

By the way

ʻ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?)

At the end

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

reference

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

Take a look at Kotlin from an Effective Java perspective
[Java] Let's take a look at Switch Expressions (Preview) of JDK 13.
Effective Java Item 25 Select a list from an array First half
A look at Jenkins, OpenJDK 8 and Java 11
[Java] Get a random value from an array
Call a method with a Kotlin callback block from Java
Java language from the perspective of Kotlin and C #
Let's take a look at the Hotspot JVM startup procedure
Let's take a look at the screen of Quant Analyzer!
Easily get an integer from a system property in Java
From Ineffective Java to Effective Java
Get a non-empty collection from an Optional stream in java
A quick look back at Java over the last five years
Introduction to Scala from a Java perspective, decompiled and understood (basic)
Let's summarize the Java 8 grammar from the perspective of an iOS engineer
Run a batch file from Java
Access Teradata from a Java application
Study memo that got a job at an IT company from inexperienced
Introduction to Scala from a Java perspective (Class-Tuple edition) to decompile and understand
Take a peek at how Processing 3 works
Re-study Docker from a system operation perspective
Try running a Kubernetes Job from Java
Memo for migration from java to kotlin
If a person from Java learns PHP
Unresolved refarence may occur at build time when referencing Java class from Kotlin
Let's take a look at the functions of Keycloak's management console (administrator edition)