Use LinkedHashMap everywhere to preserve order.

This commit is contained in:
Ilya Ryzhenkov
2014-06-11 18:10:46 +04:00
parent cb17f0c635
commit a9da7cfeea
8 changed files with 57 additions and 66 deletions
+12 -12
View File
@@ -245,84 +245,84 @@ public inline fun <T, R, C : MutableCollection<in R>> Stream<T>.flatMapTo(destin
* Returns a map of the elements in original collection grouped by the result of given *toKey* function
*/
public inline fun <T, K> Array<out T>.groupBy(toKey: (T) -> K): Map<K, List<T>> {
return groupByTo(HashMap<K, MutableList<T>>(), toKey)
return groupByTo(LinkedHashMap<K, MutableList<T>>(), toKey)
}
/**
* Returns a map of the elements in original collection grouped by the result of given *toKey* function
*/
public inline fun <K> BooleanArray.groupBy(toKey: (Boolean) -> K): Map<K, List<Boolean>> {
return groupByTo(HashMap<K, MutableList<Boolean>>(), toKey)
return groupByTo(LinkedHashMap<K, MutableList<Boolean>>(), toKey)
}
/**
* Returns a map of the elements in original collection grouped by the result of given *toKey* function
*/
public inline fun <K> ByteArray.groupBy(toKey: (Byte) -> K): Map<K, List<Byte>> {
return groupByTo(HashMap<K, MutableList<Byte>>(), toKey)
return groupByTo(LinkedHashMap<K, MutableList<Byte>>(), toKey)
}
/**
* Returns a map of the elements in original collection grouped by the result of given *toKey* function
*/
public inline fun <K> CharArray.groupBy(toKey: (Char) -> K): Map<K, List<Char>> {
return groupByTo(HashMap<K, MutableList<Char>>(), toKey)
return groupByTo(LinkedHashMap<K, MutableList<Char>>(), toKey)
}
/**
* Returns a map of the elements in original collection grouped by the result of given *toKey* function
*/
public inline fun <K> DoubleArray.groupBy(toKey: (Double) -> K): Map<K, List<Double>> {
return groupByTo(HashMap<K, MutableList<Double>>(), toKey)
return groupByTo(LinkedHashMap<K, MutableList<Double>>(), toKey)
}
/**
* Returns a map of the elements in original collection grouped by the result of given *toKey* function
*/
public inline fun <K> FloatArray.groupBy(toKey: (Float) -> K): Map<K, List<Float>> {
return groupByTo(HashMap<K, MutableList<Float>>(), toKey)
return groupByTo(LinkedHashMap<K, MutableList<Float>>(), toKey)
}
/**
* Returns a map of the elements in original collection grouped by the result of given *toKey* function
*/
public inline fun <K> IntArray.groupBy(toKey: (Int) -> K): Map<K, List<Int>> {
return groupByTo(HashMap<K, MutableList<Int>>(), toKey)
return groupByTo(LinkedHashMap<K, MutableList<Int>>(), toKey)
}
/**
* Returns a map of the elements in original collection grouped by the result of given *toKey* function
*/
public inline fun <K> LongArray.groupBy(toKey: (Long) -> K): Map<K, List<Long>> {
return groupByTo(HashMap<K, MutableList<Long>>(), toKey)
return groupByTo(LinkedHashMap<K, MutableList<Long>>(), toKey)
}
/**
* Returns a map of the elements in original collection grouped by the result of given *toKey* function
*/
public inline fun <K> ShortArray.groupBy(toKey: (Short) -> K): Map<K, List<Short>> {
return groupByTo(HashMap<K, MutableList<Short>>(), toKey)
return groupByTo(LinkedHashMap<K, MutableList<Short>>(), toKey)
}
/**
* Returns a map of the elements in original collection grouped by the result of given *toKey* function
*/
public inline fun <T, K> Iterable<T>.groupBy(toKey: (T) -> K): Map<K, List<T>> {
return groupByTo(HashMap<K, MutableList<T>>(), toKey)
return groupByTo(LinkedHashMap<K, MutableList<T>>(), toKey)
}
/**
* Returns a map of the elements in original collection grouped by the result of given *toKey* function
*/
public inline fun <T, K> Stream<T>.groupBy(toKey: (T) -> K): Map<K, List<T>> {
return groupByTo(HashMap<K, MutableList<T>>(), toKey)
return groupByTo(LinkedHashMap<K, MutableList<T>>(), toKey)
}
/**
* Returns a map of the elements in original collection grouped by the result of given *toKey* function
*/
public inline fun <K> String.groupBy(toKey: (Char) -> K): Map<K, List<Char>> {
return groupByTo(HashMap<K, MutableList<Char>>(), toKey)
return groupByTo(LinkedHashMap<K, MutableList<Char>>(), toKey)
}
/**
+12 -12
View File
@@ -511,7 +511,7 @@ public fun String.toList(): List<Char> {
* Returns Map containing all the values from the given collection indexed by *selector*
*/
public inline fun <T, K> Array<out T>.toMap(selector: (T) -> K): Map<K, T> {
val result = HashMap<K, T>()
val result = LinkedHashMap<K, T>()
for (element in this) {
result.put(selector(element), element)
}
@@ -522,7 +522,7 @@ public inline fun <T, K> Array<out T>.toMap(selector: (T) -> K): Map<K, T> {
* Returns Map containing all the values from the given collection indexed by *selector*
*/
public inline fun <K> BooleanArray.toMap(selector: (Boolean) -> K): Map<K, Boolean> {
val result = HashMap<K, Boolean>()
val result = LinkedHashMap<K, Boolean>()
for (element in this) {
result.put(selector(element), element)
}
@@ -533,7 +533,7 @@ public inline fun <K> BooleanArray.toMap(selector: (Boolean) -> K): Map<K, Boole
* Returns Map containing all the values from the given collection indexed by *selector*
*/
public inline fun <K> ByteArray.toMap(selector: (Byte) -> K): Map<K, Byte> {
val result = HashMap<K, Byte>()
val result = LinkedHashMap<K, Byte>()
for (element in this) {
result.put(selector(element), element)
}
@@ -544,7 +544,7 @@ public inline fun <K> ByteArray.toMap(selector: (Byte) -> K): Map<K, Byte> {
* Returns Map containing all the values from the given collection indexed by *selector*
*/
public inline fun <K> CharArray.toMap(selector: (Char) -> K): Map<K, Char> {
val result = HashMap<K, Char>()
val result = LinkedHashMap<K, Char>()
for (element in this) {
result.put(selector(element), element)
}
@@ -555,7 +555,7 @@ public inline fun <K> CharArray.toMap(selector: (Char) -> K): Map<K, Char> {
* Returns Map containing all the values from the given collection indexed by *selector*
*/
public inline fun <K> DoubleArray.toMap(selector: (Double) -> K): Map<K, Double> {
val result = HashMap<K, Double>()
val result = LinkedHashMap<K, Double>()
for (element in this) {
result.put(selector(element), element)
}
@@ -566,7 +566,7 @@ public inline fun <K> DoubleArray.toMap(selector: (Double) -> K): Map<K, Double>
* Returns Map containing all the values from the given collection indexed by *selector*
*/
public inline fun <K> FloatArray.toMap(selector: (Float) -> K): Map<K, Float> {
val result = HashMap<K, Float>()
val result = LinkedHashMap<K, Float>()
for (element in this) {
result.put(selector(element), element)
}
@@ -577,7 +577,7 @@ public inline fun <K> FloatArray.toMap(selector: (Float) -> K): Map<K, Float> {
* Returns Map containing all the values from the given collection indexed by *selector*
*/
public inline fun <K> IntArray.toMap(selector: (Int) -> K): Map<K, Int> {
val result = HashMap<K, Int>()
val result = LinkedHashMap<K, Int>()
for (element in this) {
result.put(selector(element), element)
}
@@ -588,7 +588,7 @@ public inline fun <K> IntArray.toMap(selector: (Int) -> K): Map<K, Int> {
* Returns Map containing all the values from the given collection indexed by *selector*
*/
public inline fun <K> LongArray.toMap(selector: (Long) -> K): Map<K, Long> {
val result = HashMap<K, Long>()
val result = LinkedHashMap<K, Long>()
for (element in this) {
result.put(selector(element), element)
}
@@ -599,7 +599,7 @@ public inline fun <K> LongArray.toMap(selector: (Long) -> K): Map<K, Long> {
* Returns Map containing all the values from the given collection indexed by *selector*
*/
public inline fun <K> ShortArray.toMap(selector: (Short) -> K): Map<K, Short> {
val result = HashMap<K, Short>()
val result = LinkedHashMap<K, Short>()
for (element in this) {
result.put(selector(element), element)
}
@@ -610,7 +610,7 @@ public inline fun <K> ShortArray.toMap(selector: (Short) -> K): Map<K, Short> {
* Returns Map containing all the values from the given collection indexed by *selector*
*/
public inline fun <T, K> Iterable<T>.toMap(selector: (T) -> K): Map<K, T> {
val result = HashMap<K, T>()
val result = LinkedHashMap<K, T>()
for (element in this) {
result.put(selector(element), element)
}
@@ -621,7 +621,7 @@ public inline fun <T, K> Iterable<T>.toMap(selector: (T) -> K): Map<K, T> {
* Returns Map containing all the values from the given collection indexed by *selector*
*/
public inline fun <T, K> Stream<T>.toMap(selector: (T) -> K): Map<K, T> {
val result = HashMap<K, T>()
val result = LinkedHashMap<K, T>()
for (element in this) {
result.put(selector(element), element)
}
@@ -632,7 +632,7 @@ public inline fun <T, K> Stream<T>.toMap(selector: (T) -> K): Map<K, T> {
* Returns Map containing all the values from the given collection indexed by *selector*
*/
public inline fun <K> String.toMap(selector: (Char) -> K): Map<K, Char> {
val result = HashMap<K, Char>()
val result = LinkedHashMap<K, Char>()
for (element in this) {
result.put(selector(element), element)
}
@@ -17,7 +17,7 @@ public fun listOf<T>(vararg values: T): List<T> = if (values.size == 0) stdlib_e
public fun listOf<T>(): List<T> = stdlib_emptyList()
/** Returns a new read-only map of given pairs, where the first value is the key, and the second is value */
public fun mapOf<K, V>(vararg values: Pair<K, V>): Map<K, V> = if (values.size == 0) stdlib_emptyMap() else hashMapOf(*values)
public fun mapOf<K, V>(vararg values: Pair<K, V>): Map<K, V> = if (values.size == 0) stdlib_emptyMap() else linkedMapOf(*values)
/** Returns an empty read-only map */
public fun mapOf<K, V>(): Map<K, V> = stdlib_emptyMap()
@@ -40,6 +40,19 @@ public fun <K, V> hashMapOf(vararg values: Pair<K, V>): HashMap<K, V> {
return answer
}
/**
* Returns a new [[LinkedHashMap]] populated with the given pairs where the first value in each pair
* 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/collections/MapTest.kt createLinkedMap
*/
public fun <K, V> linkedMapOf(vararg values: Pair<K, V>): LinkedHashMap<K, V> {
val answer = LinkedHashMap<K, V>(values.size)
answer.putAll(*values)
return answer
}
/** Returns the size of the collection */
public val Collection<*>.size: Int
get() = size()
@@ -36,25 +36,6 @@ public fun <K, V> sortedMapOf(vararg values: Pair<K, V>): SortedMap<K, V> {
return answer
}
/**
* Returns a new [[LinkedHashMap]] populated with the given pairs where the first value in each pair
* 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/collections/MapTest.kt createLinkedMap
*/
public fun <K, V> linkedMapOf(vararg values: Pair<K, V>): LinkedHashMap<K, V> {
val answer = LinkedHashMap<K, V>(values.size)
/**
TODO replace by this simpler call when we can pass vararg values into other methods
answer.putAll(values)
*/
for (v in values) {
answer.put(v.first, v.second)
}
return answer
}
/** Returns the Set if its not null otherwise returns the empty set */
public fun <T> Set<T>?.orEmpty(): Set<T>
= if (this != null) this else Collections.EMPTY_SET as Set<T>
@@ -1,7 +1,6 @@
package kotlin
import java.util.Collections
import java.util.HashMap
import java.util.*
// Map APIs
@@ -129,7 +128,7 @@ public fun <K, V> MutableMap<K, V>.putAll(values: Iterable<Pair<K,V>>): Unit {
* @includeFunctionBody ../../test/collections/MapTest.kt mapValues
*/
public inline fun <K, V, R> Map<K, V>.mapValues(transform: (Map.Entry<K, V>) -> R): Map<K, R> {
return mapValuesTo(HashMap<K, R>(this.size), transform)
return mapValuesTo(LinkedHashMap<K, R>(this.size), transform)
}
/**
@@ -138,14 +137,14 @@ public inline fun <K, V, R> Map<K, V>.mapValues(transform: (Map.Entry<K, V>) ->
* @includeFunctionBody ../../test/collections/MapTest.kt mapKeys
*/
public inline fun <K, V, R> Map<K, V>.mapKeys(transform: (Map.Entry<K, V>) -> R): Map<R, V> {
return mapKeysTo(HashMap<R, V>(this.size), transform)
return mapKeysTo(LinkedHashMap<R, V>(this.size), transform)
}
/**
* Returns a map containing all key-value pairs matching keys with the given *predicate*
*/
public inline fun <K, V> Map<K, V>.filterKeys(predicate: (K) -> Boolean): Map<K, V> {
val result = HashMap<K, V>()
val result = LinkedHashMap<K, V>()
for (entry in this) {
if (predicate(entry.key)) {
result.put(entry.key, entry.value)
@@ -158,7 +157,7 @@ public inline fun <K, V> Map<K, V>.filterKeys(predicate: (K) -> Boolean): Map<K,
* Returns a map containing all key-value pairs matching values with the given *predicate*
*/
public inline fun <K, V> Map<K, V>.filterValues(predicate: (V) -> Boolean): Map<K, V> {
val result = HashMap<K, V>()
val result = LinkedHashMap<K, V>()
for (entry in this) {
if (predicate(entry.value)) {
result.put(entry.key, entry.value)
@@ -184,7 +183,7 @@ public inline fun <K, V, C : MutableMap<K, V>> Map<K, V>.filterTo(destination: C
* Returns a map containing all key-value pairs matching the given *predicate*
*/
public inline fun <K, V> Map<K, V>.filter(predicate: (Map.Entry<K, V>) -> Boolean): Map<K, V> {
return filterTo(HashMap<K, V>(), predicate)
return filterTo(LinkedHashMap<K, V>(), predicate)
}
/**
@@ -203,7 +202,7 @@ public inline fun <K, V, C : MutableMap<K, V>> Map<K, V>.filterNotTo(destination
* Returns a map containing all key-value pairs matching the given *predicate*
*/
public inline fun <K, V> Map<K, V>.filterNot(predicate: (Map.Entry<K, V>) -> Boolean): Map<K, V> {
return filterNotTo(HashMap<K, V>(), predicate)
return filterNotTo(LinkedHashMap<K, V>(), predicate)
}
/**
@@ -217,7 +216,7 @@ public fun <K, V> MutableMap<K, V>.plusAssign(pair: Pair<K, V>) {
* Returns a map containing all key-value pairs from the given collection
*/
public fun <K, V> Iterable<Pair<K, V>>.toMap(): Map<K, V> {
val result = HashMap<K, V>()
val result = LinkedHashMap<K, V>()
for (element in this) {
result.put(element.first, element.second)
}
+9 -11
View File
@@ -1,14 +1,12 @@
package test.collections
import kotlin.test.*
import java.util.*
import org.junit.Test as test
class MapTest {
test fun getOrElse() {
val data = hashMapOf<String, Int>()
val data = mapOf<String, Int>()
val a = data.getOrElse("foo") { 2 }
assertEquals(2, a)
@@ -16,7 +14,7 @@ class MapTest {
assertEquals(3, b)
assertEquals(0, data.size())
val empty = hashMapOf<String, Int?>()
val empty = mapOf<String, Int?>()
val c = empty.getOrElse("") { null }
assertEquals(null, c)
}
@@ -91,7 +89,7 @@ class MapTest {
}
test fun contains() {
val map = hashMapOf("a" to 1, "b" to 2)
val map = mapOf("a" to 1, "b" to 2)
assert("a" in map)
assert("c" !in map)
}
@@ -121,7 +119,7 @@ class MapTest {
}
test fun createUsingPairs() {
val map = hashMapOf(Pair("a", 1), Pair("b", 2))
val map = mapOf(Pair("a", 1), Pair("b", 2))
assertEquals(2, map.size)
assertEquals(1, map["a"])
assertEquals(2, map["b"])
@@ -135,7 +133,7 @@ class MapTest {
}
test fun createUsingTo() {
val map = hashMapOf("a" to 1, "b" to 2)
val map = mapOf("a" to 1, "b" to 2)
assertEquals(2, map.size)
assertEquals(1, map["a"])
assertEquals(2, map["b"])
@@ -158,8 +156,8 @@ class MapTest {
}
test fun toSortedMap() {
val map = hashMapOf(Pair("c", 3), Pair("b", 2), Pair("a", 1))
val sorted = map.toSortedMap<String, Int>()
val map = mapOf(Pair("c", 3), Pair("b", 2), Pair("a", 1))
val sorted = map.toSortedMap()
assertEquals(1, sorted["a"])
assertEquals(2, sorted["b"])
assertEquals(3, sorted["c"])
@@ -167,7 +165,7 @@ class MapTest {
}
test fun toSortedMapWithComparator() {
val map = hashMapOf(Pair("c", 3), Pair("bc", 2), Pair("bd", 4), Pair("abc", 1))
val map = mapOf(Pair("c", 3), Pair("bc", 2), Pair("bd", 4), Pair("abc", 1))
val c = comparator<String>{ a, b ->
val answer = a.length() - b.length()
if (answer == 0) a.compareTo(b) else answer
@@ -180,7 +178,7 @@ class MapTest {
}
test fun toProperties() {
val map = hashMapOf("a" to "A", "b" to "B")
val map = mapOf("a" to "A", "b" to "B")
val prop = map.toProperties()
assertEquals(2, prop.size)
assertEquals("A", prop.getProperty("a", "fail"))