diff --git a/libraries/stdlib/jvm/src/kotlin/collections/builders/ListBuilder.kt b/libraries/stdlib/jvm/src/kotlin/collections/builders/ListBuilder.kt index d0e32bf32db..5932439a663 100644 --- a/libraries/stdlib/jvm/src/kotlin/collections/builders/ListBuilder.kt +++ b/libraries/stdlib/jvm/src/kotlin/collections/builders/ListBuilder.kt @@ -17,6 +17,9 @@ internal class ListBuilder private constructor( private val backing: ListBuilder?, private val root: ListBuilder? ) : MutableList, RandomAccess, AbstractMutableList(), Serializable { + private companion object { + private val Empty = ListBuilder(0).also { it.isReadOnly = true } + } constructor() : this(10) @@ -27,7 +30,7 @@ internal class ListBuilder private constructor( if (backing != null) throw IllegalStateException() // just in case somebody casts subList to ListBuilder checkIsMutable() isReadOnly = true - return this + return if (length > 0) this else Empty } private fun writeReplace(): Any = diff --git a/libraries/stdlib/jvm/src/kotlin/collections/builders/MapBuilder.kt b/libraries/stdlib/jvm/src/kotlin/collections/builders/MapBuilder.kt index 27c1fad36c1..8ebd141d11d 100644 --- a/libraries/stdlib/jvm/src/kotlin/collections/builders/MapBuilder.kt +++ b/libraries/stdlib/jvm/src/kotlin/collections/builders/MapBuilder.kt @@ -50,7 +50,8 @@ internal class MapBuilder private constructor( fun build(): Map { checkIsMutable() isReadOnly = true - return this + @Suppress("UNCHECKED_CAST") + return if (size > 0) this else (Empty as Map) } private fun writeReplace(): Any = @@ -459,12 +460,14 @@ internal class MapBuilder private constructor( internal fun valuesIterator() = ValuesItr(this) internal fun entriesIterator() = EntriesItr(this) - private companion object { + internal companion object { private const val MAGIC = -1640531527 // 2654435769L.toInt(), golden ratio private const val INITIAL_CAPACITY = 8 private const val INITIAL_MAX_PROBE_DISTANCE = 2 private const val TOMBSTONE = -1 + internal val Empty = MapBuilder(0).also { it.isReadOnly = true } + private fun computeHashSize(capacity: Int): Int = (capacity.coerceAtLeast(1) * 3).takeHighestOneBit() private fun computeShift(hashSize: Int): Int = hashSize.countLeadingZeroBits() + 1 diff --git a/libraries/stdlib/jvm/src/kotlin/collections/builders/SetBuilder.kt b/libraries/stdlib/jvm/src/kotlin/collections/builders/SetBuilder.kt index a5d8a6b7b09..96104235fa1 100644 --- a/libraries/stdlib/jvm/src/kotlin/collections/builders/SetBuilder.kt +++ b/libraries/stdlib/jvm/src/kotlin/collections/builders/SetBuilder.kt @@ -10,6 +10,9 @@ import java.io.NotSerializableException internal class SetBuilder internal constructor( private val backing: MapBuilder ) : MutableSet, AbstractMutableSet(), Serializable { + private companion object { + private val Empty = SetBuilder(MapBuilder.Empty) + } constructor() : this(MapBuilder()) @@ -17,7 +20,7 @@ internal class SetBuilder internal constructor( fun build(): Set { backing.build() - return this + return if (size > 0) this else Empty } private fun writeReplace(): Any =