diff --git a/libraries/stdlib/js/src/kotlin/collections/ArrayList.kt b/libraries/stdlib/js/src/kotlin/collections/ArrayList.kt index 44403520ed5..171fc2589db 100644 --- a/libraries/stdlib/js/src/kotlin/collections/ArrayList.kt +++ b/libraries/stdlib/js/src/kotlin/collections/ArrayList.kt @@ -36,7 +36,9 @@ public actual open class ArrayList internal constructor(private var array: Ar * * @throws IllegalArgumentException if [initialCapacity] is negative. */ - public actual constructor(initialCapacity: Int) : this(emptyArray()) {} + public actual constructor(initialCapacity: Int) : this(emptyArray()) { + require(initialCapacity >= 0) { "Negative initial capacity: $initialCapacity" } + } /** * Creates a new [ArrayList] filled with the elements of the specified collection. diff --git a/libraries/stdlib/js/src/kotlin/collections/HashMap.kt b/libraries/stdlib/js/src/kotlin/collections/HashMap.kt index d158eb5e401..63d98ee6d27 100644 --- a/libraries/stdlib/js/src/kotlin/collections/HashMap.kt +++ b/libraries/stdlib/js/src/kotlin/collections/HashMap.kt @@ -93,7 +93,7 @@ public actual open class HashMap : AbstractMutableMap, MutableMap : AbstractMutableSet, MutableSet { * * @throws IllegalArgumentException if [initialCapacity] is negative. */ - actual constructor(initialCapacity: Int) : this(initialCapacity, 0.0f) + actual constructor(initialCapacity: Int) : this(initialCapacity, 1.0f) /** * Protected constructor to specify the underlying map. This is used by diff --git a/libraries/stdlib/js/src/kotlin/collections/LinkedHashMap.kt b/libraries/stdlib/js/src/kotlin/collections/LinkedHashMap.kt index f7e4751e3c3..b44ef325ac3 100644 --- a/libraries/stdlib/js/src/kotlin/collections/LinkedHashMap.kt +++ b/libraries/stdlib/js/src/kotlin/collections/LinkedHashMap.kt @@ -211,7 +211,7 @@ public actual open class LinkedHashMap : HashMap, MutableMap { * * @throws IllegalArgumentException if [initialCapacity] is negative. */ - actual constructor(initialCapacity: Int) : this(initialCapacity, 0.0f) + actual constructor(initialCapacity: Int) : this(initialCapacity, 1.0f) /** * Creates a new [LinkedHashMap] filled with the contents of the specified [original] map. diff --git a/libraries/stdlib/js/src/kotlin/collections/LinkedHashSet.kt b/libraries/stdlib/js/src/kotlin/collections/LinkedHashSet.kt index 7791c73910c..190c3d91b0d 100644 --- a/libraries/stdlib/js/src/kotlin/collections/LinkedHashSet.kt +++ b/libraries/stdlib/js/src/kotlin/collections/LinkedHashSet.kt @@ -65,7 +65,7 @@ public actual open class LinkedHashSet : HashSet, MutableSet { * * @throws IllegalArgumentException if [initialCapacity] is negative. */ - actual constructor(initialCapacity: Int) : this(initialCapacity, 0.0f) + actual constructor(initialCapacity: Int) : this(initialCapacity, 1.0f) @PublishedApi internal fun build(): Set { diff --git a/libraries/stdlib/native-wasm/src/kotlin/collections/HashMap.kt b/libraries/stdlib/native-wasm/src/kotlin/collections/HashMap.kt index a006415a388..a1956b25f29 100644 --- a/libraries/stdlib/native-wasm/src/kotlin/collections/HashMap.kt +++ b/libraries/stdlib/native-wasm/src/kotlin/collections/HashMap.kt @@ -77,7 +77,9 @@ actual class HashMap private constructor( * * @throws IllegalArgumentException if [initialCapacity] is negative or [loadFactor] is non-positive. */ - actual constructor(initialCapacity: Int, loadFactor: Float) : this(initialCapacity) + actual constructor(initialCapacity: Int, loadFactor: Float) : this(initialCapacity) { + require(loadFactor > 0) { "Non-positive load factor: $loadFactor" } + } @PublishedApi internal fun build(): Map { diff --git a/libraries/stdlib/native-wasm/src/kotlin/collections/HashSet.kt b/libraries/stdlib/native-wasm/src/kotlin/collections/HashSet.kt index d62429eaa10..fe6aff55d02 100644 --- a/libraries/stdlib/native-wasm/src/kotlin/collections/HashSet.kt +++ b/libraries/stdlib/native-wasm/src/kotlin/collections/HashSet.kt @@ -52,7 +52,7 @@ actual class HashSet internal constructor( * * @throws IllegalArgumentException if [initialCapacity] is negative or [loadFactor] is non-positive. */ - actual constructor(initialCapacity: Int, loadFactor: Float) : this(initialCapacity) + actual constructor(initialCapacity: Int, loadFactor: Float) : this(HashMap(initialCapacity, loadFactor)) @PublishedApi internal fun build(): Set { diff --git a/libraries/stdlib/test/collections/CollectionTest.kt b/libraries/stdlib/test/collections/CollectionTest.kt index 08fd76614ab..10c7166f8a3 100644 --- a/libraries/stdlib/test/collections/CollectionTest.kt +++ b/libraries/stdlib/test/collections/CollectionTest.kt @@ -1261,4 +1261,47 @@ class CollectionTest { fun ensureCapacity() { ArrayList().ensureCapacity(-1) // negative argument is ignored } + + @Test + fun constructorWithCapacity() { + assertFailsWith { + ArrayList(/*initialCapacity = */-1) + } + assertEquals(0, ArrayList(/*initialCapacity = */0).size) + assertEquals(0, ArrayList(/*initialCapacity = */10).size) + + assertFailsWith { + HashSet(/*initialCapacity = */-1) + } + assertFailsWith { + HashSet(/*initialCapacity = */-1, /*loadFactor = */0.5f) + } + assertFailsWith { + HashSet(/*initialCapacity = */10, /*loadFactor = */0.0f) + } + assertFailsWith { + HashSet(/*initialCapacity = */10, /*loadFactor = */Float.NaN) + } + assertEquals(0, HashSet(/*initialCapacity = */0).size) + assertEquals(0, HashSet(/*initialCapacity = */10).size) + assertEquals(0, HashSet(/*initialCapacity = */0, /*loadFactor = */0.5f).size) + assertEquals(0, HashSet(/*initialCapacity = */10, /*loadFactor = */1.5f).size) + + assertFailsWith { + LinkedHashSet(/*initialCapacity = */-1) + } + assertFailsWith { + LinkedHashSet(/*initialCapacity = */-1, /*loadFactor = */0.5f) + } + assertFailsWith { + LinkedHashSet(/*initialCapacity = */10, /*loadFactor = */0.0f) + } + assertFailsWith { + LinkedHashSet(/*initialCapacity = */10, /*loadFactor = */Float.NaN) + } + assertEquals(0, LinkedHashSet(/*initialCapacity = */0).size) + assertEquals(0, LinkedHashSet(/*initialCapacity = */10).size) + assertEquals(0, LinkedHashSet(/*initialCapacity = */0, /*loadFactor = */0.5f).size) + assertEquals(0, LinkedHashSet(/*initialCapacity = */10, /*loadFactor = */1.5f).size) + } } diff --git a/libraries/stdlib/test/collections/MapTest.kt b/libraries/stdlib/test/collections/MapTest.kt index ef930f9ce35..4c67db9da65 100644 --- a/libraries/stdlib/test/collections/MapTest.kt +++ b/libraries/stdlib/test/collections/MapTest.kt @@ -766,4 +766,41 @@ class MapTest { assertFailsWith { empty.minOfWith(naturalOrder()) { it.toString() } } assertFailsWith { empty.maxOfWith(naturalOrder()) { it.toString() } } } + + @Test + fun constructorWithCapacity() { + assertFailsWith { + HashMap(/*initialCapacity = */-1) + } + assertFailsWith { + HashMap(/*initialCapacity = */-1, /*loadFactor = */0.5f) + } + assertFailsWith { + HashMap(/*initialCapacity = */10, /*loadFactor = */0.0f) + } + assertFailsWith { + HashMap(/*initialCapacity = */10, /*loadFactor = */Float.NaN) + } + assertEquals(0, HashMap(/*initialCapacity = */0).size) + assertEquals(0, HashMap(/*initialCapacity = */10).size) + assertEquals(0, HashMap(/*initialCapacity = */0, /*loadFactor = */0.5f).size) + assertEquals(0, HashMap(/*initialCapacity = */10, /*loadFactor = */1.5f).size) + + assertFailsWith { + LinkedHashMap(/*initialCapacity = */-1) + } + assertFailsWith { + LinkedHashMap(/*initialCapacity = */-1, /*loadFactor = */0.5f) + } + assertFailsWith { + LinkedHashMap(/*initialCapacity = */10, /*loadFactor = */0.0f) + } + assertFailsWith { + LinkedHashMap(/*initialCapacity = */10, /*loadFactor = */Float.NaN) + } + assertEquals(0, LinkedHashMap(/*initialCapacity = */0).size) + assertEquals(0, LinkedHashMap(/*initialCapacity = */10).size) + assertEquals(0, LinkedHashMap(/*initialCapacity = */0, /*loadFactor = */0.5f).size) + assertEquals(0, LinkedHashMap(/*initialCapacity = */10, /*loadFactor = */1.5f).size) + } }