Align behavoir of collection constructors across platforms #KT-59192
The initialCapacity should be non-negative and loadFactor should be positive. As a part of efforts to stabilize Native stdlib.
This commit is contained in:
committed by
Space Team
parent
0bef1533e2
commit
830c78773c
@@ -36,7 +36,9 @@ public actual open class ArrayList<E> internal constructor(private var array: Ar
|
|||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if [initialCapacity] is negative.
|
* @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.
|
* Creates a new [ArrayList] filled with the elements of the specified collection.
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public actual open class HashMap<K, V> : AbstractMutableMap<K, V>, MutableMap<K,
|
|||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if [initialCapacity] is negative.
|
* @throws IllegalArgumentException if [initialCapacity] is negative.
|
||||||
*/
|
*/
|
||||||
actual constructor(initialCapacity: Int) : this(initialCapacity, 0.0f)
|
actual constructor(initialCapacity: Int) : this(initialCapacity, 1.0f)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public actual open class HashSet<E> : AbstractMutableSet<E>, MutableSet<E> {
|
|||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if [initialCapacity] is negative.
|
* @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
|
* Protected constructor to specify the underlying map. This is used by
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ public actual open class LinkedHashMap<K, V> : HashMap<K, V>, MutableMap<K, V> {
|
|||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if [initialCapacity] is negative.
|
* @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.
|
* Creates a new [LinkedHashMap] filled with the contents of the specified [original] map.
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public actual open class LinkedHashSet<E> : HashSet<E>, MutableSet<E> {
|
|||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if [initialCapacity] is negative.
|
* @throws IllegalArgumentException if [initialCapacity] is negative.
|
||||||
*/
|
*/
|
||||||
actual constructor(initialCapacity: Int) : this(initialCapacity, 0.0f)
|
actual constructor(initialCapacity: Int) : this(initialCapacity, 1.0f)
|
||||||
|
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal fun build(): Set<E> {
|
internal fun build(): Set<E> {
|
||||||
|
|||||||
@@ -77,7 +77,9 @@ actual class HashMap<K, V> private constructor(
|
|||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if [initialCapacity] is negative or [loadFactor] is non-positive.
|
* @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
|
@PublishedApi
|
||||||
internal fun build(): Map<K, V> {
|
internal fun build(): Map<K, V> {
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ actual class HashSet<E> internal constructor(
|
|||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if [initialCapacity] is negative or [loadFactor] is non-positive.
|
* @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<E, Nothing>(initialCapacity, loadFactor))
|
||||||
|
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal fun build(): Set<E> {
|
internal fun build(): Set<E> {
|
||||||
|
|||||||
@@ -1261,4 +1261,47 @@ class CollectionTest {
|
|||||||
fun ensureCapacity() {
|
fun ensureCapacity() {
|
||||||
ArrayList<String>().ensureCapacity(-1) // negative argument is ignored
|
ArrayList<String>().ensureCapacity(-1) // negative argument is ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun constructorWithCapacity() {
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
ArrayList<String>(/*initialCapacity = */-1)
|
||||||
|
}
|
||||||
|
assertEquals(0, ArrayList<String>(/*initialCapacity = */0).size)
|
||||||
|
assertEquals(0, ArrayList<String>(/*initialCapacity = */10).size)
|
||||||
|
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
HashSet<String>(/*initialCapacity = */-1)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
HashSet<String>(/*initialCapacity = */-1, /*loadFactor = */0.5f)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
HashSet<String>(/*initialCapacity = */10, /*loadFactor = */0.0f)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
HashSet<String>(/*initialCapacity = */10, /*loadFactor = */Float.NaN)
|
||||||
|
}
|
||||||
|
assertEquals(0, HashSet<String>(/*initialCapacity = */0).size)
|
||||||
|
assertEquals(0, HashSet<String>(/*initialCapacity = */10).size)
|
||||||
|
assertEquals(0, HashSet<String>(/*initialCapacity = */0, /*loadFactor = */0.5f).size)
|
||||||
|
assertEquals(0, HashSet<String>(/*initialCapacity = */10, /*loadFactor = */1.5f).size)
|
||||||
|
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
LinkedHashSet<String>(/*initialCapacity = */-1)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
LinkedHashSet<String>(/*initialCapacity = */-1, /*loadFactor = */0.5f)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
LinkedHashSet<String>(/*initialCapacity = */10, /*loadFactor = */0.0f)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
LinkedHashSet<String>(/*initialCapacity = */10, /*loadFactor = */Float.NaN)
|
||||||
|
}
|
||||||
|
assertEquals(0, LinkedHashSet<String>(/*initialCapacity = */0).size)
|
||||||
|
assertEquals(0, LinkedHashSet<String>(/*initialCapacity = */10).size)
|
||||||
|
assertEquals(0, LinkedHashSet<String>(/*initialCapacity = */0, /*loadFactor = */0.5f).size)
|
||||||
|
assertEquals(0, LinkedHashSet<String>(/*initialCapacity = */10, /*loadFactor = */1.5f).size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -766,4 +766,41 @@ class MapTest {
|
|||||||
assertFailsWith<NoSuchElementException> { empty.minOfWith(naturalOrder()) { it.toString() } }
|
assertFailsWith<NoSuchElementException> { empty.minOfWith(naturalOrder()) { it.toString() } }
|
||||||
assertFailsWith<NoSuchElementException> { empty.maxOfWith(naturalOrder()) { it.toString() } }
|
assertFailsWith<NoSuchElementException> { empty.maxOfWith(naturalOrder()) { it.toString() } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun constructorWithCapacity() {
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
HashMap<String, String>(/*initialCapacity = */-1)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
HashMap<String, String>(/*initialCapacity = */-1, /*loadFactor = */0.5f)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
HashMap<String, String>(/*initialCapacity = */10, /*loadFactor = */0.0f)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
HashMap<String, String>(/*initialCapacity = */10, /*loadFactor = */Float.NaN)
|
||||||
|
}
|
||||||
|
assertEquals(0, HashMap<String, String>(/*initialCapacity = */0).size)
|
||||||
|
assertEquals(0, HashMap<String, String>(/*initialCapacity = */10).size)
|
||||||
|
assertEquals(0, HashMap<String, String>(/*initialCapacity = */0, /*loadFactor = */0.5f).size)
|
||||||
|
assertEquals(0, HashMap<String, String>(/*initialCapacity = */10, /*loadFactor = */1.5f).size)
|
||||||
|
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
LinkedHashMap<String, String>(/*initialCapacity = */-1)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
LinkedHashMap<String, String>(/*initialCapacity = */-1, /*loadFactor = */0.5f)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
LinkedHashMap<String, String>(/*initialCapacity = */10, /*loadFactor = */0.0f)
|
||||||
|
}
|
||||||
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
LinkedHashMap<String, String>(/*initialCapacity = */10, /*loadFactor = */Float.NaN)
|
||||||
|
}
|
||||||
|
assertEquals(0, LinkedHashMap<String, String>(/*initialCapacity = */0).size)
|
||||||
|
assertEquals(0, LinkedHashMap<String, String>(/*initialCapacity = */10).size)
|
||||||
|
assertEquals(0, LinkedHashMap<String, String>(/*initialCapacity = */0, /*loadFactor = */0.5f).size)
|
||||||
|
assertEquals(0, LinkedHashMap<String, String>(/*initialCapacity = */10, /*loadFactor = */1.5f).size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user