From efc8f2c88aff5f617c7a1c070271fbf7e091dcdd Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Fri, 13 May 2016 17:42:28 +0300 Subject: [PATCH] Provide extensions to copy maps. #KT-9108 --- .../stdlib/src/kotlin/collections/Maps.kt | 24 ++++++++++++ libraries/stdlib/test/collections/MapTest.kt | 38 ++++++++++++++----- .../reference-public-api/kotlin-stdlib.txt | 3 ++ 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/libraries/stdlib/src/kotlin/collections/Maps.kt b/libraries/stdlib/src/kotlin/collections/Maps.kt index 0135d7c5b4d..350b39ff6ca 100644 --- a/libraries/stdlib/src/kotlin/collections/Maps.kt +++ b/libraries/stdlib/src/kotlin/collections/Maps.kt @@ -438,6 +438,29 @@ public fun Sequence>.toMap(): Map = toMap(LinkedHashMap< public fun > Sequence>.toMap(destination: M): M = destination.apply { putAll(this@toMap) } +/** + * Returns a new read-only map containing all key-value pairs from the original map. + * + * The returned map preserves the entry iteration order of the original map. + */ +public fun Map.toMap(): Map = when (size) { + 0 -> emptyMap() + else -> toMutableMap() +} + +/** + * Returns a new mutable map containing all key-value pairs from the original map. + * + * The returned map preserves the entry iteration order of the original map. + */ +public fun Map.toMutableMap(): MutableMap = LinkedHashMap(this) + +/** + * Populates and returns the [destination] mutable map with key-value pairs from the given map. + */ +public fun > Map.toMap(destination: M): M + = destination.apply { putAll(this@toMap) } + /** * Creates a new read-only map by replacing or adding an entry to this map from a given key-value [pair]. * @@ -532,6 +555,7 @@ internal fun Map.optimizeReadOnlyMap() = when (size) { else -> this } +// creates a singleton copy of map, if it there is specialization available in target platform @kotlin.jvm.JvmVersion internal fun Map.toSingletonMap(): Map = with (entries.iterator().next()) { Collections.singletonMap(key, value) } diff --git a/libraries/stdlib/test/collections/MapTest.kt b/libraries/stdlib/test/collections/MapTest.kt index 723f101631c..ea1c3a4707e 100644 --- a/libraries/stdlib/test/collections/MapTest.kt +++ b/libraries/stdlib/test/collections/MapTest.kt @@ -162,18 +162,36 @@ class MapTest { assertEquals("Mells", m2["location2"]) } - @test fun createUsingPairs() { - val map = mapOf(Pair("a", 1), Pair("b", 2)) - assertEquals(2, map.size) - assertEquals(1, map["a"]) - assertEquals(2, map["b"]) + @test fun createFrom() { + val pairs = arrayOf("a" to 1, "b" to 2) + val expected = mapOf(*pairs) + + assertEquals(expected, pairs.toMap()) + assertEquals(expected, pairs.asIterable().toMap()) + assertEquals(expected, pairs.asSequence().toMap()) + assertEquals(expected, expected.toMap()) + + val mutableMap = expected.toMutableMap() + assertEquals(expected, mutableMap) + mutableMap += "c" to 3 + assertNotEquals(expected, mutableMap) } - @test fun createFromIterable() { - val map = listOf(Pair("a", 1), Pair("b", 2)).toMap() - assertEquals(2, map.size) - assertEquals(1, map.get("a")) - assertEquals(2, map.get("b")) + @test fun populateTo() { + val pairs = arrayOf("a" to 1, "b" to 2) + val expected = mapOf(*pairs) + + val linkedMap: LinkedHashMap = pairs.toMap(linkedMapOf()) + assertEquals(expected, linkedMap) + + val hashMap: HashMap = pairs.asIterable().toMap(hashMapOf()) + assertEquals(expected, hashMap) + + val mutableMap: MutableMap = pairs.asSequence().toMap(mutableMapOf()) + assertEquals(expected, mutableMap) + + val mutableMap2 = mutableMap.toMap(mutableMapOf()) + assertEquals(expected, mutableMap2) } @test fun createWithSelector() { diff --git a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib.txt b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib.txt index a730c79df5b..1e816d68dfd 100644 --- a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib.txt +++ b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib.txt @@ -1532,10 +1532,13 @@ public final class kotlin/collections/MapsKt { public static final fun toList (Ljava/util/Map;)Ljava/util/List; public static final fun toMap (Ljava/lang/Iterable;)Ljava/util/Map; public static final fun toMap (Ljava/lang/Iterable;Ljava/util/Map;)Ljava/util/Map; + public static final fun toMap (Ljava/util/Map;)Ljava/util/Map; + public static final fun toMap (Ljava/util/Map;Ljava/util/Map;)Ljava/util/Map; public static final fun toMap (Lkotlin/sequences/Sequence;)Ljava/util/Map; public static final fun toMap (Lkotlin/sequences/Sequence;Ljava/util/Map;)Ljava/util/Map; public static final fun toMap ([Lkotlin/Pair;)Ljava/util/Map; public static final fun toMap ([Lkotlin/Pair;Ljava/util/Map;)Ljava/util/Map; + public static final fun toMutableMap (Ljava/util/Map;)Ljava/util/Map; public static final fun toSortedMap (Ljava/util/Map;)Ljava/util/SortedMap; public static final fun toSortedMap (Ljava/util/Map;Ljava/util/Comparator;)Ljava/util/SortedMap; public static final fun withDefault (Ljava/util/Map;Lkotlin/jvm/functions/Function1;)Ljava/util/Map;