web-dev-qa-db-ja.com

コトリンにおける平等

私はC++とJava=バックグラウンドでKotlinを学習しています。以下はtrueではなくfalseを出力することを期待していました。そのことを知っています==equalsにマップされます。equalsのデフォルトの実装では、各メンバー、つまりfirstNamelastNameは比較されませんか?そうであれば、表示されませんか?等しい文字列値(==equalに再びマップされるため)?明らかに、Kotlinでまだ正しくない、同等性と同一性に関連するものがあります。

class MyPerson(val firstName: String, val lastName: String)

fun main(args: Array<String>) {
   println(MyPerson("Charlie", "Parker") == MyPerson("Charlie", "Parker"))
}
12
Dabbler

説明しているデフォルトのequals実装は、データクラスにのみ存在します。実装がObjectから継承される通常のクラスではなく、オブジェクトをそれ自体と等しくするだけです。

7
JB Nizet

参照の平等

Java

Javaでは、equalsのデフォルト実装は変数の reference を比較します。これは==alwaysが行うことです。

クラスequalsObjectメソッドは、オブジェクトに対して最も区別可能な可能な等価関係を実装します。つまり、null以外の参照値xおよびyの場合、このメソッドはtrueif if if only if xand y refer to the same objectx == yの値はtrue)です。

これを「参照等しい」と呼びます。

Kotlin

Kotlinでは、==equalsにコンパイルされますが、===はJavaの==に相当します。

構造的平等

referential等価ではなくstructuralが必要なときはいつでも、equalsをオーバーライドできます。これはnevernormalクラスのデフォルトでは、あなたが提案したように行われます。 Kotlinでは、data classを使用できます。コンパイラーは、コンストラクターのプロパティに基づいて実装を自動的に作成します(読み取り here )。

hashCodeをオーバーライドする場合は常にequalsをオーバーライドすることを忘れないでください(逆も同様)manuallyと両方のメソッドの非常に厳密な contracts に固執します。 Kotlinのコンパイラー生成の実装は、契約を満たしています。

30
s1m0nw1

==等しい場合

Javaでは、==を使用してプリミティブ型と参照型を比較できます。プリミティブ型に適用すると、Javaの==は値を比較しますが、参照型の==は参照を比較します。したがって、Javaでは、常に「等しい」を呼び出すというよく知られた慣行があり、そうすることを忘れるというよく知られた問題があります。

Kotlinでは、2つのオブジェクトを比較するデフォルトの方法は==です。内部でequalsを呼び出すことにより、それらの値を比較します。したがって、クラスでequalsがオーバーライドされている場合は、==を使用してインスタンスを安全に比較できます。参照比較には、===演算子を使用できます。これは、Javaの==とまったく同じように機能します。

class MyPerson(val firstName: String, val lastName: String){
    override fun equals(other: Any?): Boolean {
        if (other == null || other !is MyPerson) return false
        return firstName == other.firstName && lastName == other.lastName
    }
}

fun main(args: Array<String>) {
    println(MyPerson("Charlie", "Parker") == MyPerson("Charlie", "Parker")) // print "true"
}

あなたの場合、MyPersondata classこれは、ユニバーサルメソッドの実装を自動生成します(toStringequals、およびhashCode)。

4
Chulo