diff --git a/libraries/stdlib/src/kotlin/JUtil.kt b/libraries/stdlib/src/kotlin/JUtil.kt index e744fd26494..98ac1dabfab 100644 --- a/libraries/stdlib/src/kotlin/JUtil.kt +++ b/libraries/stdlib/src/kotlin/JUtil.kt @@ -64,7 +64,7 @@ public inline fun sortedMap(vararg values: #(K,V)): SortedMap { * is the key and the second value is the value. This map preserves insertion order so iterating through * the map's entries will be in the same order * - * @includeFunctionBody ../../test/MapTest.kt createLinkedHashMap + * @includeFunctionBody ../../test/MapTest.kt createLinkedMap */ public inline fun linkedMap(vararg values: #(K,V)): LinkedHashMap { val answer = LinkedHashMap(values.size) diff --git a/libraries/stdlib/src/kotlin/JUtilMaps.kt b/libraries/stdlib/src/kotlin/JUtilMaps.kt index 9f0fd4b9dd0..fb2012a788d 100644 --- a/libraries/stdlib/src/kotlin/JUtilMaps.kt +++ b/libraries/stdlib/src/kotlin/JUtilMaps.kt @@ -6,6 +6,11 @@ import java.util.Collection import java.util.Collections import java.util.HashMap import java.util.List +import java.util.LinkedHashMap +import java.util.Map +import java.util.TreeMap +import java.util.SortedMap +import java.util.Comparator // Map APIs @@ -121,4 +126,32 @@ public inline fun java.util.Map.putAll(vararg values: #(K,V)): Unit { for (v in values) { put(v._1, v._2) } -} \ No newline at end of file +} + +/** + * Converts this [[Map]] to a [[LinkedHashMap]] so future insertion orders are maintained + */ +public inline fun java.util.Map.toLinkedMap(): LinkedHashMap = toMap(LinkedHashMap(size)) as LinkedHashMap + +/** + * Converts this [[Map]] to a [[SortedMap]] so iteration order will be in key order + * + * @includeFunctionBody ../../test/MapTest.kt toSortedMap + */ +public inline fun java.util.Map.toSortedMap(): SortedMap = toMap(TreeMap()) as SortedMap + +/** + * Converts this [[Map]] to a [[SortedMap]] using the given *comparator* so that iteration order will be in the order + * defined by the comparator + * + * @includeFunctionBody ../../test/MapTest.kt toSortedMapWithComparator + */ +public inline fun java.util.Map.toSortedMap(comparator: Comparator): SortedMap = toMap(TreeMap(comparator)) as SortedMap + +/** + * Copies the entries in this [[Map]] to the given *map* + */ +public inline fun java.util.Map.toMap(map: Map): Map { + map.putAll(this) + return map +} diff --git a/libraries/stdlib/src/kotlin/Ordering.kt b/libraries/stdlib/src/kotlin/Ordering.kt index cacbd2fdff7..b5ed2be58aa 100644 --- a/libraries/stdlib/src/kotlin/Ordering.kt +++ b/libraries/stdlib/src/kotlin/Ordering.kt @@ -51,6 +51,7 @@ public inline fun comparator(vararg functions: Function1): Comparato return FunctionComparator(functions) } + private class FunctionComparator(val functions: Array>): Comparator { public fun toString(): String { @@ -61,6 +62,30 @@ private class FunctionComparator(val functions: Array>): C return compareBy(o1, o2, *functions) } + public override fun equals(obj: Any?): Boolean { + return this == obj + } +} + +/** + * Creates a comparator using the sequence of functions used to calculate a value to compare on + */ +public inline fun comparator(fn: (T,T) -> Int): Comparator { + return Function2Comparator(fn) +} +private class Function2Comparator(val compareFn: (T,T) -> Int): Comparator { + + public fun toString(): String { + return "Function2Comparator${compareFn}" + } + + public override fun compare(a: T?, b: T?): Int { + if (a === b) return 0 + if (a == null) return - 1 + if (b == null) return 1 + return (compareFn)(a, b) + } + public override fun equals(obj: Any?): Boolean { return this == obj } diff --git a/libraries/stdlib/test/MapTest.kt b/libraries/stdlib/test/MapTest.kt index 9b149f2d370..f003bd977f6 100644 --- a/libraries/stdlib/test/MapTest.kt +++ b/libraries/stdlib/test/MapTest.kt @@ -121,7 +121,6 @@ class MapTest { test fun createLinkedMap() { val map = linkedMap(#("c", 3), #("b", 2), #("a", 1)) - assertEquals(3, map.size) assertEquals(1, map.get("a")) assertEquals(2, map.get("b")) assertEquals(3, map.get("c")) @@ -130,13 +129,34 @@ class MapTest { test fun createSortedMap() { val map = sortedMap(#("c", 3), #("b", 2), #("a", 1)) - assertEquals(3, map.size) assertEquals(1, map.get("a")) assertEquals(2, map.get("b")) assertEquals(3, map.get("c")) assertEquals(arrayList("a", "b", "c"), map.keySet()!!.toList()) } + test fun toSortedMap() { + val map = hashMap(#("c", 3), #("b", 2), #("a", 1)) + val sorted = map.toSortedMap() + assertEquals(1, sorted.get("a")) + assertEquals(2, sorted.get("b")) + assertEquals(3, sorted.get("c")) + assertEquals(arrayList("a", "b", "c"), sorted.keySet()!!.toList()) + } + + test fun toSortedMapWithComparator() { + val map = hashMap(#("c", 3), #("bc", 2), #("bd", 4), #("abc", 1)) + val c = comparator{ a, b -> + val answer = a.length() - b.length() + if (answer == 0) a.compareTo(b) else answer + } + val sorted = map.toSortedMap(c) + assertEquals(arrayList("c", "bc", "bd", "abc"), sorted.keySet()!!.toList()) + assertEquals(1, sorted.get("abc")) + assertEquals(2, sorted.get("bc")) + assertEquals(3, sorted.get("c")) + } + /** TODO test case for http://youtrack.jetbrains.com/issue/KT-1773