1. 概要

このチュートリアルでは、Kotlin配列の等価性チェックを行う方法を学習します。

2. 平等

Kotlinには、参照と構造の平等という2種類の平等があります。 さらに、 ===演算子を使用して参照の同等性をチェックし、==演算子を使用して構造的同等性をチェックすることができます

firstsecondという名前の2つの配列を同じ値で定義し、後でfirst[と同じオブジェクトを指すthird配列を定義しましょう。 X176X]アレイ:

val first = arrayOf("java", "python", "kotlin")
val second = arrayOf("java", "python", "kotlin")
val third = first

次に、これらの配列間の参照が等しいかどうかを確認しましょう。

Assertions.assertTrue(first === third)
Assertions.assertFalse(first === second)
Assertions.assertFalse(second === third)

次に、これらの配列間の構造が等しいかどうかを確認しましょう。

Assertions.assertTrue(first == third)
Assertions.assertFalse(first == second)
Assertions.assertFalse(second == third)

まず、1番目と2番目の配列は構造的に等しいものの、 ==演算子は、それらを構造的にチェックするための期待される動作を示さないことに注意する必要があります

次のセクションでは、Kotlinで配列の構造的同等性チェックを実行する方法について説明します。

3. contentEquals関数

contentEquals 関数は、Kotlinの infix関数であり、配列の構造比較に使用できます。

以前と同じ配列、つまり first second 、および third を使用して、contentEquals関数の動作を確認してみましょう。 :

val first = arrayOf("java", "python", "kotlin")
val second = arrayOf("java", "python", "kotlin")
val third = first

Assertions.assertTrue(first contentEquals third)
Assertions.assertTrue(first contentEquals second)
Assertions.assertTrue(second contentEquals third)

予想どおり、 contentEquals 関数を使用すると、3つの配列すべてが構造的に同じであると断言できます。

次に、ネストされた配列– r1 r2 、およびr3があるシナリオを考えてみましょう。

val r1 = arrayOf(arrayOf("R1", "R2"), arrayOf("R3", "R4"))
val r2 = arrayOf(arrayOf("R1", "R2"), arrayOf("R3", "R4"))
val r3 = r1

ここで、これらのネストされた配列の包括的な構造比較を行わないため、contentEquals関数に制限があることがわかります。

Assertions.assertTrue(r1 contentEquals r3)
Assertions.assertFalse(r1 contentEquals r2)
Assertions.assertFalse(r2 contentEquals r3)

4. contentDeepEquals関数

Kotlinは、 contentDeepEquals インフィックス関数を提供して、ネストされた配列の場合のcontentEquals関数の構造的等式比較の制限を解決します。

contentDeepEquals 関数を使用して、ネストされた配列の同じセットを比較してみましょう。

val r1 = arrayOf(arrayOf("R1", "R2"), arrayOf("R3", "R4"))
val r2 = arrayOf(arrayOf("R1", "R2"), arrayOf("R3", "R4"))
val r3 = r1

Assertions.assertTrue(r1 contentDeepEquals r3)
Assertions.assertTrue(r1 contentDeepEquals r2)
Assertions.assertTrue(r2 contentDeepEquals r3)

予想どおり、3つのネストされた配列の構造的同等性が確認されていることがわかります。

5. ユーザー定義オブジェクトの配列

これまで、文字列値の配列の比較を見てきました。 それでは、先に進んで理解を深め、ユーザー定義のオブジェクトを含む配列を比較してみましょう。

Person class を定義し、Personクラスのインスタンスを含む2つの配列を初期化します。

class Person (var name: String?, var age: Int?)
val first = arrayOf(Person("John", 20), Person("Mary", 15))
val second = arrayOf(Person("John", 20), Person("Mary", 15))

このようなシナリオでは、contentEquals関数は配列の構造比較を行うことができません

Assertions.assertFalse(first contentEquals second)

これはです。これは、Personクラスでequals()メソッドを定義していないためです。その結果、 contentEquals 関数は、デフォルトで参照等価性チェックを実行します。

Person クラスをデータクラスとして定義することで、この問題を解決できます。

data class Person (var name: String?, var age: Int?)
val first = arrayOf(Person("John", 20), Person("Mary", 15))
val second = arrayOf(Person("John", 20), Person("Mary", 15))

Assertions.assertTrue(first contentEquals second)

データクラスは本質的に値の比較のためにequals()メソッドを定義するため、Person[のオブジェクトを含むfirstおよびsecond配列をアサートできます。 X183X]タイプは構造的に同じです。

さらに、 contentDeepEquals 関数を使用して、Personタイプのオブジェクトを保持するネストされた配列の構造的同等性を検証することもできます。

data class Person (var name: String?, var age: Int?)
val p1 = arrayOf(arrayOf(Person("John", 20), Person("Mary", 15)))
val p2 = arrayOf(arrayOf(Person("John", 20), Person("Mary", 15)))
Assertions.assertTrue(p1 contentDeepEquals p2)

6. 結論

この記事では、Kotlinで1次元のネストされた配列の等価性チェックを行う方法について理解を深めました。

いつものように、ソースコードはGitHubから入手できます。