Do not recreate entries, keys and values collections on each access to property.
This commit is contained in:
@@ -48,33 +48,37 @@ public abstract class AbstractMutableMap<K, V> protected constructor() : Abstrac
|
|||||||
entries.clear()
|
entries.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var _keys: MutableSet<K>? = null
|
||||||
override val keys: MutableSet<K> get() {
|
override val keys: MutableSet<K> get() {
|
||||||
return object : AbstractMutableSet<K>() {
|
if (_keys == null) {
|
||||||
override fun clear() {
|
_keys = object : AbstractMutableSet<K>() {
|
||||||
this@AbstractMutableMap.clear()
|
override fun clear() {
|
||||||
}
|
this@AbstractMutableMap.clear()
|
||||||
|
|
||||||
override operator fun contains(element: K): Boolean = containsKey(element)
|
|
||||||
|
|
||||||
override operator fun iterator(): MutableIterator<K> {
|
|
||||||
val outerIter = entries.iterator()
|
|
||||||
return object : MutableIterator<K> {
|
|
||||||
override fun hasNext(): Boolean = outerIter.hasNext()
|
|
||||||
override fun next(): K = outerIter.next().key
|
|
||||||
override fun remove() = outerIter.remove()
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun remove(element: K): Boolean {
|
override operator fun contains(element: K): Boolean = containsKey(element)
|
||||||
if (containsKey(element)) {
|
|
||||||
this@AbstractMutableMap.remove(element)
|
override operator fun iterator(): MutableIterator<K> {
|
||||||
return true
|
val entryIterator = entries.iterator()
|
||||||
|
return object : MutableIterator<K> {
|
||||||
|
override fun hasNext(): Boolean = entryIterator.hasNext()
|
||||||
|
override fun next(): K = entryIterator.next().key
|
||||||
|
override fun remove() = entryIterator.remove()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override val size: Int get() = this@AbstractMutableMap.size
|
override fun remove(element: K): Boolean {
|
||||||
|
if (containsKey(element)) {
|
||||||
|
this@AbstractMutableMap.remove(element)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override val size: Int get() = this@AbstractMutableMap.size
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return _keys!!
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun put(key: K, value: V): V? {
|
override fun put(key: K, value: V): V? {
|
||||||
@@ -87,31 +91,35 @@ public abstract class AbstractMutableMap<K, V> protected constructor() : Abstrac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var _values: MutableCollection<V>? = null
|
||||||
override val values: MutableCollection<V> get() {
|
override val values: MutableCollection<V> get() {
|
||||||
return object : AbstractMutableCollection<V>() {
|
if (_values == null) {
|
||||||
override fun clear() = this@AbstractMutableMap.clear()
|
_values = object : AbstractMutableCollection<V>() {
|
||||||
|
override fun clear() = this@AbstractMutableMap.clear()
|
||||||
|
|
||||||
override operator fun contains(element: V): Boolean = containsValue(element)
|
override operator fun contains(element: V): Boolean = containsValue(element)
|
||||||
|
|
||||||
override operator fun iterator(): MutableIterator<V> {
|
override operator fun iterator(): MutableIterator<V> {
|
||||||
val outerIter = entries.iterator()
|
val entryIterator = entries.iterator()
|
||||||
return object : MutableIterator<V> {
|
return object : MutableIterator<V> {
|
||||||
override fun hasNext(): Boolean = outerIter.hasNext()
|
override fun hasNext(): Boolean = entryIterator.hasNext()
|
||||||
override fun next(): V = outerIter.next().value
|
override fun next(): V = entryIterator.next().value
|
||||||
override fun remove() = outerIter.remove()
|
override fun remove() = entryIterator.remove()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override val size: Int get() = this@AbstractMutableMap.size
|
override val size: Int get() = this@AbstractMutableMap.size
|
||||||
|
|
||||||
// TODO: should we implement them this way? Currently it's unspecified in JVM
|
// TODO: should we implement them this way? Currently it's unspecified in JVM
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other !is Collection<*>) return false
|
if (other !is Collection<*>) return false
|
||||||
return AbstractList.orderedEquals(this, other)
|
return AbstractList.orderedEquals(this, other)
|
||||||
|
}
|
||||||
|
override fun hashCode(): Int = AbstractList.orderedHashCode(this)
|
||||||
}
|
}
|
||||||
override fun hashCode(): Int = AbstractList.orderedHashCode(this)
|
|
||||||
}
|
}
|
||||||
|
return _values!!
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun remove(key: K): V? {
|
override fun remove(key: K): V? {
|
||||||
|
|||||||
@@ -80,8 +80,15 @@ public open class HashMap<K, V> : AbstractMutableMap<K, V> {
|
|||||||
|
|
||||||
override fun containsValue(value: V): Boolean = internalMap.any { equality.equals(it.value, value) }
|
override fun containsValue(value: V): Boolean = internalMap.any { equality.equals(it.value, value) }
|
||||||
|
|
||||||
override val entries: MutableSet<MutableMap.MutableEntry<K, V>>
|
private var _entries: MutableSet<MutableMap.MutableEntry<K, V>>? = null
|
||||||
get() = EntrySet()
|
override val entries: MutableSet<MutableMap.MutableEntry<K, V>> get() {
|
||||||
|
if (_entries == null) {
|
||||||
|
_entries = createEntrySet()
|
||||||
|
}
|
||||||
|
return _entries!!
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun createEntrySet(): MutableSet<MutableMap.MutableEntry<K, V>> = EntrySet()
|
||||||
|
|
||||||
override operator fun get(key: K): V? = internalMap.get(key)
|
override operator fun get(key: K): V? = internalMap.get(key)
|
||||||
|
|
||||||
|
|||||||
@@ -201,8 +201,7 @@ public open class LinkedHashMap<K, V> : HashMap<K, V>, Map<K, V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override val entries: MutableSet<MutableMap.MutableEntry<K, V>>
|
override fun createEntrySet(): MutableSet<MutableMap.MutableEntry<K, V>> = EntrySet()
|
||||||
get() = EntrySet()
|
|
||||||
|
|
||||||
override operator fun get(key: K): V? = map.get(key)?.value
|
override operator fun get(key: K): V? = map.get(key)?.value
|
||||||
|
|
||||||
|
|||||||
@@ -62,21 +62,24 @@ public abstract class AbstractMap<K, out V> protected constructor() : Map<K, V>
|
|||||||
override fun isEmpty(): Boolean = size == 0
|
override fun isEmpty(): Boolean = size == 0
|
||||||
override val size: Int get() = entries.size
|
override val size: Int get() = entries.size
|
||||||
|
|
||||||
|
private @Volatile var _keys: Set<K>? = null
|
||||||
override val keys: Set<K> get() {
|
override val keys: Set<K> get() {
|
||||||
return object : AbstractSet<K>() {
|
if (_keys == null) {
|
||||||
override operator fun contains(element: K): Boolean = containsKey(element)
|
_keys = object : AbstractSet<K>() {
|
||||||
|
override operator fun contains(element: K): Boolean = containsKey(element)
|
||||||
|
|
||||||
override operator fun iterator(): Iterator<K> {
|
override operator fun iterator(): Iterator<K> {
|
||||||
val outerIter = entries.iterator()
|
val entryIterator = entries.iterator()
|
||||||
return object : Iterator<K> {
|
return object : Iterator<K> {
|
||||||
override fun hasNext(): Boolean = outerIter.hasNext()
|
override fun hasNext(): Boolean = entryIterator.hasNext()
|
||||||
override fun next(): K = outerIter.next().key
|
override fun next(): K = entryIterator.next().key
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override val size: Int get() = this@AbstractMap.size
|
override val size: Int get() = this@AbstractMap.size
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return _keys!!
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String = entries.joinToString(", ", "{", "}") { toString(it) }
|
override fun toString(): String = entries.joinToString(", ", "{", "}") { toString(it) }
|
||||||
@@ -85,28 +88,33 @@ public abstract class AbstractMap<K, out V> protected constructor() : Map<K, V>
|
|||||||
|
|
||||||
private fun toString(o: Any?): String = if (o === this) "(this Map)" else o.toString()
|
private fun toString(o: Any?): String = if (o === this) "(this Map)" else o.toString()
|
||||||
|
|
||||||
|
private @Volatile var _values: Collection<V>? = null
|
||||||
override val values: Collection<V> get() {
|
override val values: Collection<V> get() {
|
||||||
return object : AbstractCollection<V>() {
|
if (_values == null) {
|
||||||
override operator fun contains(element: @UnsafeVariance V): Boolean = containsValue(element)
|
_values = object : AbstractCollection<V>() {
|
||||||
|
override operator fun contains(element: @UnsafeVariance V): Boolean = containsValue(element)
|
||||||
|
|
||||||
override operator fun iterator(): Iterator<V> {
|
override operator fun iterator(): Iterator<V> {
|
||||||
val outerIter = entries.iterator()
|
val entryIterator = entries.iterator()
|
||||||
return object : Iterator<V> {
|
return object : Iterator<V> {
|
||||||
override fun hasNext(): Boolean = outerIter.hasNext()
|
override fun hasNext(): Boolean = entryIterator.hasNext()
|
||||||
override fun next(): V = outerIter.next().value
|
override fun next(): V = entryIterator.next().value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override val size: Int get() = this@AbstractMap.size
|
override val size: Int get() = this@AbstractMap.size
|
||||||
|
|
||||||
// TODO: should we implement them this way? Currently it's unspecified in JVM
|
// TODO: should we implement them this way? Currently it's unspecified in JVM
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other !is Collection<*>) return false
|
if (other !is Collection<*>) return false
|
||||||
return AbstractList.orderedEquals(this, other)
|
return AbstractList.orderedEquals(this, other)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int = AbstractList.orderedHashCode(this)
|
||||||
}
|
}
|
||||||
override fun hashCode(): Int = AbstractList.orderedHashCode(this)
|
|
||||||
}
|
}
|
||||||
|
return _values!!
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun implFindEntry(key: K): Map.Entry<K, V>? = entries.firstOrNull { it.key == key }
|
private fun implFindEntry(key: K): Map.Entry<K, V>? = entries.firstOrNull { it.key == key }
|
||||||
|
|||||||
Reference in New Issue
Block a user