Optimize the implementation of emptyList, emptySet and emptyMap and make them serializable.

Specialized implementations of singleton List, Set and Map are used in JVM.

#KT-6682 Fixed
#KT-7104 Fixed
#KT-4840 Fixed
This commit is contained in:
Ilya Gorbunov
2015-05-14 21:25:43 +03:00
parent b7277cd80c
commit edc471c8ec
6 changed files with 143 additions and 61 deletions
@@ -1,54 +1,76 @@
package kotlin
import java.io.Serializable
import java.util.*
private object EmptyList : List<Any> {
private val list = ArrayList<Any>()
override fun contains(o: Any?): Boolean = list.contains(o)
override fun containsAll(c: Collection<Any?>): Boolean = list.containsAll(c)
override fun get(index: Int): Any = list.get(index)
override fun indexOf(o: Any?): Int = list.indexOf(o)
override fun isEmpty(): Boolean = list.isEmpty()
override fun iterator(): Iterator<Any> = list.iterator()
override fun lastIndexOf(o: Any?): Int = list.lastIndexOf(o)
override fun listIterator(): ListIterator<Any> = list.listIterator()
override fun listIterator(index: Int): ListIterator<Any> =list.listIterator(index)
override fun size(): Int = list.size()
override fun subList(fromIndex: Int, toIndex: Int): List<Any> = list.subList(fromIndex, toIndex)
override fun equals(other: Any?): Boolean = list.equals(other)
override fun hashCode(): Int = list.hashCode()
override fun toString(): String = list.toString()
private object EmptyIterator : ListIterator<Nothing> {
override fun hasNext(): Boolean = false
override fun hasPrevious(): Boolean = false
override fun nextIndex(): Int = 0
override fun previousIndex(): Int = -1
override fun next(): Nothing = throw NoSuchElementException()
override fun previous(): Nothing = throw NoSuchElementException()
}
private object EmptySet : Set<Any> {
private val set = HashSet<Any>()
private object EmptyList : List<Nothing>, Serializable {
override fun equals(other: Any?): Boolean = other is List<*> && other.isEmpty()
override fun hashCode(): Int = 1
override fun toString(): String = "[]"
override fun contains(o: Any?): Boolean = set.contains(o)
override fun containsAll(c: Collection<Any?>): Boolean = set.containsAll(c)
override fun isEmpty(): Boolean = set.isEmpty()
override fun iterator(): Iterator<Any> = set.iterator()
override fun size(): Int = set.size()
override fun equals(other: Any?): Boolean = set.equals(other)
override fun hashCode(): Int = set.hashCode()
override fun toString(): String = set.toString()
override fun size(): Int = 0
override fun isEmpty(): Boolean = true
override fun contains(o: Any?): Boolean = false
override fun containsAll(c: Collection<Any?>): Boolean = c.isEmpty()
override fun get(index: Int): Nothing = throw IndexOutOfBoundsException("Index $index is out of bound of empty list.")
override fun indexOf(o: Any?): Int = -1
override fun lastIndexOf(o: Any?): Int = -1
override fun iterator(): Iterator<Nothing> = EmptyIterator
override fun listIterator(): ListIterator<Nothing> = EmptyIterator
override fun listIterator(index: Int): ListIterator<Nothing> {
if (index != 0) throw IndexOutOfBoundsException("Index: $index")
return EmptyIterator
}
override fun subList(fromIndex: Int, toIndex: Int): List<Nothing> {
if (fromIndex == 0 && toIndex == 0) return this
throw IndexOutOfBoundsException("fromIndex: $fromIndex, toIndex: $toIndex")
}
private fun readResolve(): Any = EmptyList
}
/** Returns an empty read-only list. */
public fun emptyList<T>(): List<T> = EmptyList as List<T>
/** Returns an empty read-only set. */
public fun emptySet<T>(): Set<T> = EmptySet as Set<T>
private object EmptySet : Set<Nothing>, Serializable {
override fun equals(other: Any?): Boolean = other is Set<*> && other.isEmpty()
override fun hashCode(): Int = 0
override fun toString(): String = "[]"
/** Returns a new read-only list of given elements */
public fun listOf<T>(vararg values: T): List<T> = if (values.size() == 0) emptyList() else arrayListOf(*values)
override fun size(): Int = 0
override fun isEmpty(): Boolean = true
override fun contains(o: Any?): Boolean = false
override fun containsAll(c: Collection<Any?>): Boolean = c.isEmpty()
/** Returns an empty read-only list. */
override fun iterator(): Iterator<Nothing> = EmptyIterator
private fun readResolve(): Any = EmptySet
}
/** Returns an empty read-only list. The returned list is serializable (JVM). */
public fun emptyList<T>(): List<T> = EmptyList
/** Returns an empty read-only set. The returned set is serializable (JVM). */
public fun emptySet<T>(): Set<T> = EmptySet
/** Returns a new read-only list of given elements. The returned list is serializable (JVM). */
public fun listOf<T>(vararg values: T): List<T> = if (values.size() > 0) arrayListOf(*values) else emptyList()
/** Returns an empty read-only list. The returned list is serializable (JVM). */
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>(mapCapacity(values.size())))
/** Returns a new read-only ordered set with the given elements. The returned set is serializable (JVM). */
public fun setOf<T>(vararg values: T): Set<T> = if (values.size() > 0) values.toSet() else emptySet()
/** Returns an empty read-only set. */
/** Returns an empty read-only set. The returned set is serializable (JVM). */
public fun setOf<T>(): Set<T> = emptySet()
/** Returns a new [LinkedList] with the given elements. */
@@ -2,6 +2,25 @@ package kotlin
import java.util.*
/**
* Returns an immutable list containing only the specified object [value].
* The returned list is serializable.
*/
public fun listOf<T>(value: T): List<T> = Collections.singletonList(value)
/**
* Returns an immutable set containing only the specified object [value].
* The returned set is serializable.
*/
public fun setOf<T>(value: T): Set<T> = Collections.singleton(value)
/**
* Returns an immutable map, mapping only the specified key to the
* specified value. The returned map is serializable.
*/
public fun mapOf<K, V>(keyValuePair: Pair<K, V>): Map<K, V> = Collections.singletonMap(keyValuePair.first, keyValuePair.second)
/**
* Returns a new [SortedSet] with the given elements.
*/
+22 -18
View File
@@ -1,34 +1,39 @@
package kotlin
import java.io.Serializable
import java.util.*
private object EmptyMap : Map<Any, Any> {
private val map = HashMap<Any, Any>()
private object EmptyMap : Map<Any, Nothing>, Serializable {
override fun equals(other: Any?): Boolean = other is Map<*,*> && other.isEmpty()
override fun hashCode(): Int = 0
override fun toString(): String = "{}"
override fun containsKey(key: Any?): Boolean = map.containsKey(key)
override fun containsValue(value: Any?): Boolean = map.containsValue(value)
override fun entrySet(): Set<Map.Entry<Any, Any>> = map.entrySet()
override fun get(key: Any?): Any? = map.get(key)
override fun keySet(): Set<Any> = map.keySet()
override fun values(): Collection<Any> = map.values()
override fun isEmpty(): Boolean = map.isEmpty()
override fun size(): Int = map.size()
override fun equals(other: Any?): Boolean = map.equals(other)
override fun hashCode(): Int = map.hashCode()
override fun toString(): String = map.toString()
override fun size(): Int = 0
override fun isEmpty(): Boolean = true
override fun containsKey(key: Any?): Boolean = false
override fun containsValue(value: Any?): Boolean = false
override fun get(key: Any?): Nothing? = null
override fun entrySet(): Set<Map.Entry<Any, Nothing>> = EmptySet
override fun keySet(): Set<Any> = EmptySet
override fun values(): Collection<Nothing> = EmptyList
private fun readResolve(): Any = EmptyMap
}
/** Returns an empty read-only map of specified type */
/** Returns an empty read-only map of specified type. The returned map is serializable (JVM). */
public fun emptyMap<K, V>(): Map<K, V> = EmptyMap as Map<K, V>
/**
* Returns a new read-only map with the specified contents, given as a list of pairs
* where the first value is the key and the second is the value. If multiple pairs have
* the same key, the resulting map will contain the value from the last of those pairs.
*
* The returned map is serializable (JVM).
*/
public fun mapOf<K, V>(vararg values: Pair<K, V>): Map<K, V> = if (values.size() == 0) emptyMap() else linkedMapOf(*values)
public fun mapOf<K, V>(vararg values: Pair<K, V>): Map<K, V> = if (values.size() > 0) linkedMapOf(*values) else emptyMap()
/** Returns an empty read-only map */
/** Returns an empty read-only map. The returned map is serializable (JVM). */
public fun mapOf<K, V>(): Map<K, V> = emptyMap()
/**
@@ -77,8 +82,7 @@ private fun mapCapacity(expectedSize: Int): Int {
/**
* Returns the [Map] if its not null, or the empty [Map] otherwise.
*/
public fun <K,V> Map<K,V>?.orEmpty() : Map<K,V>
= if (this != null) this else emptyMap()
public fun <K,V> Map<K,V>?.orEmpty() : Map<K,V> = this ?: emptyMap()
/**
* Checks if the map contains the given key. This method allows to use the `x in map` syntax for checking
@@ -68,12 +68,7 @@ public fun <T> sequenceOf(progression: Progression<T>): Sequence<T> = object : S
public fun <T> emptySequence(): Sequence<T> = EmptySequence
private object EmptySequence : Sequence<Nothing> {
override fun iterator(): Iterator<Nothing> = EmptySequenceIterator
}
private object EmptySequenceIterator : Iterator<Nothing> {
override fun next(): Nothing = throw NoSuchElementException("Sequence is empty.")
override fun hasNext(): Boolean = false
override fun iterator(): Iterator<Nothing> = EmptyIterator
}
deprecated("Use FilteringSequence<T> instead")