Collection performance improvements

Lists

- For arrays, use Arrays.asList, then toArrayList making the list creation an array copy
- For the same reason, use the ArrayList(Collection) constructor
- Replace duplicate code in toList, instead calling toArrayList

Maps/Sets

- Where the size of the source is known, precalculate the capacity, using the formula used by Guava's Maps class
- For toMap where we're unable to get at the private function, use HashSet's formula where the size is known
- Add a toMap that takes a selector and a transform, avoiding a separate step for transforming values
This commit is contained in:
Danny Thomas
2015-04-24 16:04:38 -07:00
committed by Ilya Gorbunov
parent 0e6babc96b
commit 7ce0487b7e
4 changed files with 363 additions and 118 deletions
+230 -92
View File
@@ -14,88 +14,77 @@ import java.util.Collections // TODO: it's temporary while we have java.util.Col
* Returns an ArrayList of all elements
*/
public fun <T> Array<out T>.toArrayList(): ArrayList<T> {
val list = ArrayList<T>(size())
for (item in this) list.add(item)
return list
return this.asList().toArrayList()
}
/**
* Returns an ArrayList of all elements
*/
public fun BooleanArray.toArrayList(): ArrayList<Boolean> {
val list = ArrayList<Boolean>(size())
for (item in this) list.add(item)
return list
return this.asList().toArrayList()
}
/**
* Returns an ArrayList of all elements
*/
public fun ByteArray.toArrayList(): ArrayList<Byte> {
val list = ArrayList<Byte>(size())
for (item in this) list.add(item)
return list
return this.asList().toArrayList()
}
/**
* Returns an ArrayList of all elements
*/
public fun CharArray.toArrayList(): ArrayList<Char> {
val list = ArrayList<Char>(size())
for (item in this) list.add(item)
return list
return this.asList().toArrayList()
}
/**
* Returns an ArrayList of all elements
*/
public fun DoubleArray.toArrayList(): ArrayList<Double> {
val list = ArrayList<Double>(size())
for (item in this) list.add(item)
return list
return this.asList().toArrayList()
}
/**
* Returns an ArrayList of all elements
*/
public fun FloatArray.toArrayList(): ArrayList<Float> {
val list = ArrayList<Float>(size())
for (item in this) list.add(item)
return list
return this.asList().toArrayList()
}
/**
* Returns an ArrayList of all elements
*/
public fun IntArray.toArrayList(): ArrayList<Int> {
val list = ArrayList<Int>(size())
for (item in this) list.add(item)
return list
return this.asList().toArrayList()
}
/**
* Returns an ArrayList of all elements
*/
public fun LongArray.toArrayList(): ArrayList<Long> {
val list = ArrayList<Long>(size())
for (item in this) list.add(item)
return list
return this.asList().toArrayList()
}
/**
* Returns an ArrayList of all elements
*/
public fun ShortArray.toArrayList(): ArrayList<Short> {
val list = ArrayList<Short>(size())
for (item in this) list.add(item)
return list
return this.asList().toArrayList()
}
/**
* Returns an ArrayList of all elements
*/
public fun <T> Collection<T>.toArrayList(): ArrayList<T> {
return ArrayList(this)
}
/**
* Returns an ArrayList of all elements
*/
public fun <T> Iterable<T>.toArrayList(): ArrayList<T> {
return toCollection(ArrayList<T>(collectionSizeOrDefault(10)))
return toCollection(ArrayList<T>())
}
/**
@@ -257,70 +246,70 @@ public fun <C : MutableCollection<in Char>> String.toCollection(collection: C):
* Returns a HashSet of all elements
*/
public fun <T> Array<out T>.toHashSet(): HashSet<T> {
return toCollection(HashSet<T>())
return toCollection(HashSet<T>(mapCapacity(size())))
}
/**
* Returns a HashSet of all elements
*/
public fun BooleanArray.toHashSet(): HashSet<Boolean> {
return toCollection(HashSet<Boolean>())
return toCollection(HashSet<Boolean>(mapCapacity(size())))
}
/**
* Returns a HashSet of all elements
*/
public fun ByteArray.toHashSet(): HashSet<Byte> {
return toCollection(HashSet<Byte>())
return toCollection(HashSet<Byte>(mapCapacity(size())))
}
/**
* Returns a HashSet of all elements
*/
public fun CharArray.toHashSet(): HashSet<Char> {
return toCollection(HashSet<Char>())
return toCollection(HashSet<Char>(mapCapacity(size())))
}
/**
* Returns a HashSet of all elements
*/
public fun DoubleArray.toHashSet(): HashSet<Double> {
return toCollection(HashSet<Double>())
return toCollection(HashSet<Double>(mapCapacity(size())))
}
/**
* Returns a HashSet of all elements
*/
public fun FloatArray.toHashSet(): HashSet<Float> {
return toCollection(HashSet<Float>())
return toCollection(HashSet<Float>(mapCapacity(size())))
}
/**
* Returns a HashSet of all elements
*/
public fun IntArray.toHashSet(): HashSet<Int> {
return toCollection(HashSet<Int>())
return toCollection(HashSet<Int>(mapCapacity(size())))
}
/**
* Returns a HashSet of all elements
*/
public fun LongArray.toHashSet(): HashSet<Long> {
return toCollection(HashSet<Long>())
return toCollection(HashSet<Long>(mapCapacity(size())))
}
/**
* Returns a HashSet of all elements
*/
public fun ShortArray.toHashSet(): HashSet<Short> {
return toCollection(HashSet<Short>())
return toCollection(HashSet<Short>(mapCapacity(size())))
}
/**
* Returns a HashSet of all elements
*/
public fun <T> Iterable<T>.toHashSet(): HashSet<T> {
return toCollection(HashSet<T>())
return toCollection(HashSet<T>(mapCapacity(collectionSizeOrDefault(12))))
}
/**
@@ -343,7 +332,7 @@ public fun <T> Stream<T>.toHashSet(): HashSet<T> {
* Returns a HashSet of all elements
*/
public fun String.toHashSet(): HashSet<Char> {
return toCollection(HashSet<Char>())
return toCollection(HashSet<Char>(mapCapacity(length())))
}
/**
@@ -453,95 +442,77 @@ public fun <K, V> Map<K, V>.toList(): List<Pair<K, V>> {
* Returns a List containing all elements
*/
public fun <T> Array<out T>.toList(): List<T> {
val list = ArrayList<T>(size())
for (item in this) list.add(item)
return list
return this.toArrayList()
}
/**
* Returns a List containing all elements
*/
public fun BooleanArray.toList(): List<Boolean> {
val list = ArrayList<Boolean>(size())
for (item in this) list.add(item)
return list
return this.toArrayList()
}
/**
* Returns a List containing all elements
*/
public fun ByteArray.toList(): List<Byte> {
val list = ArrayList<Byte>(size())
for (item in this) list.add(item)
return list
return this.toArrayList()
}
/**
* Returns a List containing all elements
*/
public fun CharArray.toList(): List<Char> {
val list = ArrayList<Char>(size())
for (item in this) list.add(item)
return list
return this.toArrayList()
}
/**
* Returns a List containing all elements
*/
public fun DoubleArray.toList(): List<Double> {
val list = ArrayList<Double>(size())
for (item in this) list.add(item)
return list
return this.toArrayList()
}
/**
* Returns a List containing all elements
*/
public fun FloatArray.toList(): List<Float> {
val list = ArrayList<Float>(size())
for (item in this) list.add(item)
return list
return this.toArrayList()
}
/**
* Returns a List containing all elements
*/
public fun IntArray.toList(): List<Int> {
val list = ArrayList<Int>(size())
for (item in this) list.add(item)
return list
return this.toArrayList()
}
/**
* Returns a List containing all elements
*/
public fun LongArray.toList(): List<Long> {
val list = ArrayList<Long>(size())
for (item in this) list.add(item)
return list
return this.toArrayList()
}
/**
* Returns a List containing all elements
*/
public fun ShortArray.toList(): List<Short> {
val list = ArrayList<Short>(size())
for (item in this) list.add(item)
return list
return this.toArrayList()
}
/**
* Returns a List containing all elements
*/
public fun <T> Iterable<T>.toList(): List<T> {
return toCollection(ArrayList<T>(collectionSizeOrDefault(10)))
return this.toArrayList()
}
/**
* Returns a List containing all elements
*/
public fun <T> Sequence<T>.toList(): List<T> {
return toCollection(ArrayList<T>())
return this.toArrayList()
}
@@ -550,21 +521,22 @@ deprecated("Migrate to using Sequence<T> and respective functions")
* Returns a List containing all elements
*/
public fun <T> Stream<T>.toList(): List<T> {
return toCollection(ArrayList<T>())
return this.toArrayList()
}
/**
* Returns a List containing all elements
*/
public fun String.toList(): List<Char> {
return toCollection(ArrayList<Char>(length()))
return this.toArrayList()
}
/**
* 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 = LinkedHashMap<K, T>()
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, T>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), element)
}
@@ -575,7 +547,8 @@ 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 = LinkedHashMap<K, Boolean>()
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, Boolean>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), element)
}
@@ -586,7 +559,8 @@ 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 = LinkedHashMap<K, Byte>()
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, Byte>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), element)
}
@@ -597,7 +571,8 @@ 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 = LinkedHashMap<K, Char>()
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, Char>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), element)
}
@@ -608,7 +583,8 @@ 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 = LinkedHashMap<K, Double>()
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, Double>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), element)
}
@@ -619,7 +595,8 @@ 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 = LinkedHashMap<K, Float>()
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, Float>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), element)
}
@@ -630,7 +607,8 @@ 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 = LinkedHashMap<K, Int>()
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, Int>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), element)
}
@@ -641,7 +619,8 @@ 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 = LinkedHashMap<K, Long>()
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, Long>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), element)
}
@@ -652,7 +631,8 @@ 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 = LinkedHashMap<K, Short>()
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, Short>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), element)
}
@@ -663,7 +643,8 @@ 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 = LinkedHashMap<K, T>()
val capacity = (collectionSizeOrDefault(10)/.75f) + 1
val result = LinkedHashMap<K, T>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), element)
}
@@ -698,81 +679,238 @@ 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 = LinkedHashMap<K, Char>()
val capacity = (length()/.75f) + 1
val result = LinkedHashMap<K, Char>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), element)
}
return result
}
/**
* Returns Map containing all the values provided by *transform* and indexed by *selector* from the given collection
*/
public inline fun <T, K, V> Array<out T>.toMap(selector: (T) -> K, transform: (T) -> V): Map<K, V> {
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, V>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), transform(element))
}
return result
}
/**
* Returns Map containing all the values provided by *transform* and indexed by *selector* from the given collection
*/
public inline fun <K, V> BooleanArray.toMap(selector: (Boolean) -> K, transform: (Boolean) -> V): Map<K, V> {
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, V>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), transform(element))
}
return result
}
/**
* Returns Map containing all the values provided by *transform* and indexed by *selector* from the given collection
*/
public inline fun <K, V> ByteArray.toMap(selector: (Byte) -> K, transform: (Byte) -> V): Map<K, V> {
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, V>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), transform(element))
}
return result
}
/**
* Returns Map containing all the values provided by *transform* and indexed by *selector* from the given collection
*/
public inline fun <K, V> CharArray.toMap(selector: (Char) -> K, transform: (Char) -> V): Map<K, V> {
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, V>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), transform(element))
}
return result
}
/**
* Returns Map containing all the values provided by *transform* and indexed by *selector* from the given collection
*/
public inline fun <K, V> DoubleArray.toMap(selector: (Double) -> K, transform: (Double) -> V): Map<K, V> {
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, V>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), transform(element))
}
return result
}
/**
* Returns Map containing all the values provided by *transform* and indexed by *selector* from the given collection
*/
public inline fun <K, V> FloatArray.toMap(selector: (Float) -> K, transform: (Float) -> V): Map<K, V> {
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, V>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), transform(element))
}
return result
}
/**
* Returns Map containing all the values provided by *transform* and indexed by *selector* from the given collection
*/
public inline fun <K, V> IntArray.toMap(selector: (Int) -> K, transform: (Int) -> V): Map<K, V> {
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, V>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), transform(element))
}
return result
}
/**
* Returns Map containing all the values provided by *transform* and indexed by *selector* from the given collection
*/
public inline fun <K, V> LongArray.toMap(selector: (Long) -> K, transform: (Long) -> V): Map<K, V> {
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, V>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), transform(element))
}
return result
}
/**
* Returns Map containing all the values provided by *transform* and indexed by *selector* from the given collection
*/
public inline fun <K, V> ShortArray.toMap(selector: (Short) -> K, transform: (Short) -> V): Map<K, V> {
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, V>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), transform(element))
}
return result
}
/**
* Returns Map containing all the values provided by *transform* and indexed by *selector* from the given collection
*/
public inline fun <T, K, V> Iterable<T>.toMap(selector: (T) -> K, transform: (T) -> V): Map<K, V> {
val capacity = (collectionSizeOrDefault(10)/.75f) + 1
val result = LinkedHashMap<K, V>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), transform(element))
}
return result
}
/**
* Returns Map containing all the values provided by *transform* and indexed by *selector* from the given collection
*/
public inline fun <T, K, V> Sequence<T>.toMap(selector: (T) -> K, transform: (T) -> V): Map<K, V> {
val result = LinkedHashMap<K, V>()
for (element in this) {
result.put(selector(element), transform(element))
}
return result
}
deprecated("Migrate to using Sequence<T> and respective functions")
/**
* Returns Map containing all the values provided by *transform* and indexed by *selector* from the given collection
*/
public inline fun <T, K, V> Stream<T>.toMap(selector: (T) -> K, transform: (T) -> V): Map<K, V> {
val result = LinkedHashMap<K, V>()
for (element in this) {
result.put(selector(element), transform(element))
}
return result
}
/**
* Returns Map containing all the values provided by *transform* and indexed by *selector* from the given collection
*/
public inline fun <K, V> String.toMap(selector: (Char) -> K, transform: (Char) -> V): Map<K, V> {
val capacity = (length()/.75f) + 1
val result = LinkedHashMap<K, V>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), transform(element))
}
return result
}
/**
* Returns a Set of all elements
*/
public fun <T> Array<out T>.toSet(): Set<T> {
return toCollection(LinkedHashSet<T>())
return toCollection(LinkedHashSet<T>(mapCapacity(size())))
}
/**
* Returns a Set of all elements
*/
public fun BooleanArray.toSet(): Set<Boolean> {
return toCollection(LinkedHashSet<Boolean>())
return toCollection(LinkedHashSet<Boolean>(mapCapacity(size())))
}
/**
* Returns a Set of all elements
*/
public fun ByteArray.toSet(): Set<Byte> {
return toCollection(LinkedHashSet<Byte>())
return toCollection(LinkedHashSet<Byte>(mapCapacity(size())))
}
/**
* Returns a Set of all elements
*/
public fun CharArray.toSet(): Set<Char> {
return toCollection(LinkedHashSet<Char>())
return toCollection(LinkedHashSet<Char>(mapCapacity(size())))
}
/**
* Returns a Set of all elements
*/
public fun DoubleArray.toSet(): Set<Double> {
return toCollection(LinkedHashSet<Double>())
return toCollection(LinkedHashSet<Double>(mapCapacity(size())))
}
/**
* Returns a Set of all elements
*/
public fun FloatArray.toSet(): Set<Float> {
return toCollection(LinkedHashSet<Float>())
return toCollection(LinkedHashSet<Float>(mapCapacity(size())))
}
/**
* Returns a Set of all elements
*/
public fun IntArray.toSet(): Set<Int> {
return toCollection(LinkedHashSet<Int>())
return toCollection(LinkedHashSet<Int>(mapCapacity(size())))
}
/**
* Returns a Set of all elements
*/
public fun LongArray.toSet(): Set<Long> {
return toCollection(LinkedHashSet<Long>())
return toCollection(LinkedHashSet<Long>(mapCapacity(size())))
}
/**
* Returns a Set of all elements
*/
public fun ShortArray.toSet(): Set<Short> {
return toCollection(LinkedHashSet<Short>())
return toCollection(LinkedHashSet<Short>(mapCapacity(size())))
}
/**
* Returns a Set of all elements
*/
public fun <T> Iterable<T>.toSet(): Set<T> {
return toCollection(LinkedHashSet<T>())
return toCollection(LinkedHashSet<T>(mapCapacity(collectionSizeOrDefault(12))))
}
/**
@@ -795,7 +933,7 @@ public fun <T> Stream<T>.toSet(): Set<T> {
* Returns a Set of all elements
*/
public fun String.toSet(): Set<Char> {
return toCollection(LinkedHashSet<Char>())
return toCollection(LinkedHashSet<Char>(mapCapacity(length())))
}
/**
@@ -46,7 +46,7 @@ public fun listOf<T>(vararg values: T): List<T> = if (values.size() == 0) emptyL
public fun listOf<T>(): List<T> = emptyList()
/** Returns a new read-only ordered set with the given elements. */
public fun setOf<T>(vararg values: T): Set<T> = if (values.size() == 0) emptySet() else values.toCollection(LinkedHashSet<T>())
public fun setOf<T>(vararg values: T): Set<T> = if (values.size() == 0) emptySet() else values.toCollection(LinkedHashSet<T>(mapCapacityForValues(values)))
/** Returns an empty read-only set. */
public fun setOf<T>(): Set<T> = emptySet()
@@ -58,10 +58,10 @@ public fun linkedListOf<T>(vararg values: T): LinkedList<T> = values.toCollectio
public fun arrayListOf<T>(vararg values: T): ArrayList<T> = values.toCollection(ArrayList(values.size()))
/** Returns a new [HashSet] with the given elements. */
public fun hashSetOf<T>(vararg values: T): HashSet<T> = values.toCollection(HashSet(values.size()))
public fun hashSetOf<T>(vararg values: T): HashSet<T> = values.toCollection(HashSet(mapCapacityForValues(values)))
/** Returns a new [LinkedHashSet] with the given elements. */
public fun linkedSetOf<T>(vararg values: T): LinkedHashSet<T> = values.toCollection(LinkedHashSet(values.size()))
public fun linkedSetOf<T>(vararg values: T): LinkedHashSet<T> = values.toCollection(LinkedHashSet(mapCapacityForValues(values)))
/**
* Returns an [IntRange] of the valid indices for this collection.
@@ -38,7 +38,7 @@ public fun mapOf<K, V>(): Map<K, V> = emptyMap()
* @sample test.collections.MapTest.createUsingPairs
*/
public fun <K, V> hashMapOf(vararg values: Pair<K, V>): HashMap<K, V> {
val answer = HashMap<K, V>(values.size())
val answer = HashMap<K, V>(mapCapacityForValues(values))
answer.putAll(*values)
return answer
}
@@ -51,11 +51,33 @@ public fun <K, V> hashMapOf(vararg values: Pair<K, V>): HashMap<K, V> {
* @sample test.collections.MapTest.createLinkedMap
*/
public fun <K, V> linkedMapOf(vararg values: Pair<K, V>): LinkedHashMap<K, V> {
val answer = LinkedHashMap<K, V>(values.size())
val answer = LinkedHashMap<K, V>(mapCapacityForValues(values))
answer.putAll(*values)
return answer
}
/**
* Calculate the initial capacity of a map, based on Guava's com.google.common.collect.Maps approach. This is equivalent
* to the Collection constructor for HashSet, (c.size()/.75f) + 1, but provides further optimisations for very small or
* very large sizes, allows support non-collection classes, and provides consistency for all map based class construction.
*/
private val MAX_POWER_OF_TWO: Int = 1 shl (Integer.SIZE - 2)
private fun mapCapacity(expectedSize: Int): Int {
if (expectedSize < 3) {
return expectedSize + 1
}
if (expectedSize < MAX_POWER_OF_TWO) {
return expectedSize + expectedSize / 3
}
return Integer.MAX_VALUE // any large value
}
private fun <T> mapCapacityForValues(values: Array<T>): Int {
return mapCapacity(values.size())
}
/**
* Returns the [Map] if its not null, or the empty [Map] otherwise.
*/
@@ -1,6 +1,7 @@
package templates
import templates.Family.*
import java.util.ArrayList
fun snapshots(): List<GenericFunction> {
val templates = arrayListOf<GenericFunction>()
@@ -22,13 +23,19 @@ fun snapshots(): List<GenericFunction> {
templates add f("toSet()") {
doc { "Returns a Set of all elements" }
returns("Set<T>")
body { "return toCollection(LinkedHashSet<T>())" }
body { "return toCollection(LinkedHashSet<T>(mapCapacity(collectionSizeOrDefault(12))))" }
body(Sequences) { "return toCollection(LinkedHashSet<T>())" }
body(Strings) { "return toCollection(LinkedHashSet<T>(mapCapacity(length())))" }
body(ArraysOfObjects, ArraysOfPrimitives) { "return toCollection(LinkedHashSet<T>(mapCapacity(size())))" }
}
templates add f("toHashSet()") {
doc { "Returns a HashSet of all elements" }
returns("HashSet<T>")
body { "return toCollection(HashSet<T>())" }
body { "return toCollection(HashSet<T>(mapCapacity(collectionSizeOrDefault(12))))" }
body(Sequences) { "return toCollection(HashSet<T>())" }
body(Strings) { "return toCollection(HashSet<T>(mapCapacity(length())))" }
body(ArraysOfObjects, ArraysOfPrimitives) { "return toCollection(HashSet<T>(mapCapacity(size())))" }
}
templates add f("toSortedSet()") {
@@ -40,16 +47,10 @@ fun snapshots(): List<GenericFunction> {
templates add f("toArrayList()") {
doc { "Returns an ArrayList of all elements" }
returns("ArrayList<T>")
body { "return toCollection(ArrayList<T>(collectionSizeOrDefault(10)))" }
body(Sequences) { "return toCollection(ArrayList<T>())" }
body { "return toCollection(ArrayList<T>())" }
body(Collections) { "return ArrayList(this)" }
body(Strings) { "return toCollection(ArrayList<T>(length()))" }
body(ArraysOfObjects, ArraysOfPrimitives) {
"""
val list = ArrayList<T>(size())
for (item in this) list.add(item)
return list
"""
}
body(ArraysOfObjects, ArraysOfPrimitives) { "return this.asList().toArrayList()" }
}
templates add f("toList()") {
@@ -69,16 +70,7 @@ fun snapshots(): List<GenericFunction> {
templates add f("toList()") {
doc { "Returns a List containing all elements" }
returns("List<T>")
body { "return toCollection(ArrayList<T>(collectionSizeOrDefault(10)))" }
body(Sequences) { "return toCollection(ArrayList<T>())" }
body(Strings) { "return toCollection(ArrayList<T>(length()))" }
body(ArraysOfObjects, ArraysOfPrimitives) {
"""
val list = ArrayList<T>(size())
for (item in this) list.add(item)
return list
"""
}
body { "return this.toArrayList()" }
}
templates add f("toLinkedList()") {
@@ -96,7 +88,23 @@ fun snapshots(): List<GenericFunction> {
"""
}
returns("Map<K, T>")
/**
* Collection size helper methods are private, so we fall back to the calculation from HashSet's Collection
* constructor.
*/
body {
"""
val capacity = (collectionSizeOrDefault(10)/.75f) + 1
val result = LinkedHashMap<K, T>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), element)
}
return result
"""
}
body(Sequences) {
"""
val result = LinkedHashMap<K, T>()
for (element in this) {
@@ -105,6 +113,83 @@ fun snapshots(): List<GenericFunction> {
return result
"""
}
body(Strings) {
"""
val capacity = (length()/.75f) + 1
val result = LinkedHashMap<K, T>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), element)
}
return result
"""
}
body(ArraysOfObjects, ArraysOfPrimitives) {
"""
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, T>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), element)
}
return result
"""
}
}
templates add f("toMap(selector: (T) -> K, transform: (T) -> V)") {
inline(true)
typeParam("K")
typeParam("V")
doc {
"""
Returns Map containing all the values provided by *transform* and indexed by *selector* from the given collection
"""
}
returns("Map<K, V>")
/**
* Collection size helper methods are private, so we fall back to the calculation from HashSet's Collection
* constructor.
*/
body {
"""
val capacity = (collectionSizeOrDefault(10)/.75f) + 1
val result = LinkedHashMap<K, V>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), transform(element))
}
return result
"""
}
body(Sequences) {
"""
val result = LinkedHashMap<K, V>()
for (element in this) {
result.put(selector(element), transform(element))
}
return result
"""
}
body(Strings) {
"""
val capacity = (length()/.75f) + 1
val result = LinkedHashMap<K, V>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), transform(element))
}
return result
"""
}
body(ArraysOfObjects, ArraysOfPrimitives) {
"""
val capacity = (size()/.75f) + 1
val result = LinkedHashMap<K, V>(Math.max(capacity.toInt(), 16))
for (element in this) {
result.put(selector(element), transform(element))
}
return result
"""
}
}
return templates