Kotlinでリストをマップに変換する

1前書き

このクイックチュートリアルでは、 List Map i _n _ Kotlinに変換する方法を説明します。

2実装

Kotlinは便利なhttps://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/to-map.html[ toMap ]メソッドを提供します。これは複雑なオブジェクトのリストを与えられて、私たちの中に要素を持つことを可能にします。私たちが提供する値でマップされたリスト:

val user1 = User("John", 18, listOf("Hiking"))
val user2 = User("Sara", 25, listOf("Chess"))
val user3 = User("Dave", 34, listOf("Games"))

@Test
fun givenList__whenConvertToMap__thenResult() {
    val myList = listOf(user1, user2, user3)
    val myMap = myList.map { it.name to it.age }.toMap()

    assertTrue(myMap.get("John") == 18)
}

“ to” キーワードは、名前と年齢のペアを作成するためにここで使用されていることに注意してください。このメソッドは、配列内の要素の入力順序を保持したマップを返します。

{John=18, Sara=25, Dave=34}

String の小さい配列をマップしたときも同じことが起こります。

@Test
fun givenStringList__whenConvertToMap__thenResult() {
    val myList = listOf("a", "b", "c")
    val myMap = myList.map { it to it }.toMap()

    assertTrue(myMap.get("a") == "a")
}

唯一の違いは it の値は指定されていないことです。

次に、 List Map に変換する2番目の方法として、 associatedBy メソッドを使用する方法があります。

@Test
fun givenList__whenAssociatedBy__thenResult() {
    val myList = listOf(user1, user2, user3)
    val myMap = myList.associateBy({ it.name }, { it.hobbies })

    assertTrue(myMap.get("John")!!.contains("Hiking"))
}

値として配列を使用するようにテストを変更しました。

{
    John=[Hiking, Swimming],
    Sara=[Chess, Board Games],
    Dave=[Games, Racing sports]}

3どちらを使うべきですか?

両方の方法が本質的に同じ機能を達成する場合、どちらを使用すればよいですか?

実装に関しては、 toMap がより直感的です。ただし、このメソッドを使用するには、最初に Array Pairs に変換する必要があります。これは後で Map に変換する必要があります。

他のタイプのコレクションの場合は、 associate APIが最良の選択です。

4 associate メソッド** を使ったマッピング

前の例では、 associateBy メソッドを使用しましたが、Kotlin collections パッケージには、使用例ごとにバージョンが異なります。

4.1. associate() メソッド

まず associate メソッドを使用します。これは、配列の要素に対して変換関数を使用して Map を返すだけです。

@Test
fun givenStringList__whenAssociate__thenResult() {
    val myList = listOf("a", "b", "c", "d")
    val myMap = myList.associate{ it to it }

    assertTrue(myMap.get("a") == "a")
}

4.2. associateTo メソッド

この方法を使うと、既存のマップに要素を集めることができます。

@Test
fun givenStringList__whenAssociateTo__thenResult() {
    val myList = listOf("a", "b", "c", "c", "b")
    val myMap = mutableMapOf<String, String>()

    myList.associateTo(myMap) {it to it}

    assertTrue(myMap.get("a") == "a")
}

変更可能な__Mapを使用することを忘れないでください - この例は不変のものでは動作しません。

4.3. associateByTo メソッド

associateByTo は、3つの中で最も柔軟性があります。移入されるマップである keySelector 関数を渡すことができるからです。指定された各キーについて、関連付けられた値は、キーが次の場所から抽出されたオブジェクトになります。

@Test
fun givenStringList__whenAssociateByToUser__thenResult() {
    val myList = listOf(user1, user2, user3, user4)
    val myMap = mutableMapOf<String, User>()

    myList.associateByTo(myMap) {it.name}

    assertTrue(myMap.get("Dave")!!.age == 34)
}

あるいは、 valueTransform 関数を使うこともできます。

@Test
fun givenStringList__whenAssociateByTo__thenResult() {
    val myList = listOf(user1, user2, user3, user4)
    val myMap = mutableMapOf<String, Int>()

    myList.associateByTo(myMap, {it.name}, {it.age})

    assertTrue(myMap.get("Dave") == 34)
}
  • キーの衝突が発生した場合、最後に追加された値のみが保持されることを覚えておくことが重要です。**

5結論

この記事では、Kotlinで List Map に変換するさまざまな方法を調べました。

いつものように、これらすべての例とスニペットの実装はhttps://github.com/eugenp/tutorials/tree/master/core-kotlin[GitHubで動く]にあります。これはMavenベースのプロジェクトなので、インポートして実行するのは簡単なはずです。