Kotlinでのオブジェクトの比較
1. 概要
このチュートリアルでは、Kotlinでのオブジェクト比較のさまざまな方法を探ります。
=== とそれに対応する!== は、参照IDに使用される二項演算子です。 これは、2つの参照が同じオブジェクトを指している場合、結果が真になることを意味します。 ただし、ほとんどの場合、2つのオブジェクトが同等の値を持っているかどうかを確認する必要があります。
それでは、Kotlinの構造的平等のさまざまな方法を調査してみましょう。
2. ==演算子を使用した等式
==とその反対の!=は、2つのオブジェクトを比較するために使用されます。2つの文字列を== と比較すると、目的の結果が得られます。
val a = "Baeldung"
val b = "Baeldung"
assertTrue(a == b)
class Storage(private val name: String, private val capacity: Int)
次に、このクラスの2つのインスタンスを比較してみましょう。
val storage1 = Storage("980Pro M.2 NVMe", 1024)
val storage2 = Storage("980Pro M.2 NVMe", 1024)
assertFalse(storage1 == storage2)
ただし、 Storage クラスでは、storage1とstorage2が等しいかどうかを明示的に指定する必要があります。 それ以外の場合は、IDチェックが行われます。 つまり、参照を照合することによって同等性をチェックします。 その場合、 storage1 == storage2はfalseを返します。
3. equals()および hashCode()をオーバーライドする
== 演算子を使用するたびに、内部で equals()関数が呼び出されます。 そして、前述のように、IDチェックが行われます。 equals()をオーバーライドして、カスタムの等価性チェックの実装を提供できます:
class StorageOverriddenEquals(val name: String, val capacity: Int) {
override fun equals(other: Any?): Boolean {
if (other == null) return false
if (this === other) return true
if (other !is StorageOverriddenEquals) return false
if (name != other.name || capacity != other.capacity) return false
return true
}
}
これで、 equals()の答えは true であり、私たちにとって意味があります。
val storage1 = StorageOverriddenEquals("980Pro M.2 NVMe", 1024)
val storage2 = StorageOverriddenEquals("980Pro M.2 NVMe", 1024)
assertTrue(storage1 == storage2)
重要な点は、equals()メソッドとhashCode()メソッドの両方を常に一緒にオーバーライドする必要があるということです。理由はハッシュコードコントラクトです。
ルールを尊重しないと、Setsなどのハッシュベースのコレクションが正しく機能しません。これを修正するには、 hashCode()関数をオーバーライドできます。
class StorageOverriddenEqualsAndHashCode(private val name: String, private val capacity: Int) {
override fun equals(other: Any?): Boolean {
if (other == null) return false
if (this === other) return true
if (other !is StorageOverriddenEqualsAndHashCode) return false
other as StorageOverriddenEqualsAndHashCode
if (name != other.name || capacity != other.capacity) return false
return true
}
override fun hashCode(): Int = name.hashCode() * 31 + capacity
}
4. データクラスの使用
または、データクラスを使用して、オブジェクトを比較するために必要な定型文を回避できます。
data class StorageDataClass(private val name: String, private val capacity: Int)
val storage1 = StorageDataClass("980Pro M.2 NVMe", 1024)
val storage2 = StorageDataClass("980Pro M.2 NVMe", 1024)
assertTrue(storage1 == storage2)
この比較の結果は真実です。
5. 結論
この記事では、==演算子のデフォルトの動作をオーバーライドする方法を説明しました。
すべての例は、GitHubでから入手できます。