Add removeFirst(OrNull) and removeLast(OrNull) methods to MutableList
This commit is contained in:
@@ -44,14 +44,6 @@ public inline fun <@kotlin.internal.OnlyInputTypes T> MutableCollection<out T>.r
|
|||||||
public inline fun <@kotlin.internal.OnlyInputTypes T> MutableCollection<out T>.retainAll(elements: Collection<T>): Boolean =
|
public inline fun <@kotlin.internal.OnlyInputTypes T> MutableCollection<out T>.retainAll(elements: Collection<T>): Boolean =
|
||||||
@Suppress("UNCHECKED_CAST") (this as MutableCollection<T>).retainAll(elements)
|
@Suppress("UNCHECKED_CAST") (this as MutableCollection<T>).retainAll(elements)
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the element at the specified [index] from this list.
|
|
||||||
* In Kotlin one should use the [MutableList.removeAt] function instead.
|
|
||||||
*/
|
|
||||||
@Deprecated("Use removeAt(index) instead.", ReplaceWith("removeAt(index)"), level = DeprecationLevel.ERROR)
|
|
||||||
@kotlin.internal.InlineOnly
|
|
||||||
public inline fun <T> MutableList<T>.remove(index: Int): T = removeAt(index)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the specified [element] to this mutable collection.
|
* Adds the specified [element] to this mutable collection.
|
||||||
*/
|
*/
|
||||||
@@ -149,71 +141,6 @@ public fun <T> MutableCollection<in T>.addAll(elements: Array<out T>): Boolean {
|
|||||||
return addAll(elements.asList())
|
return addAll(elements.asList())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all elements from this [MutableIterable] that match the given [predicate].
|
|
||||||
*
|
|
||||||
* @return `true` if any element was removed from this collection, or `false` when no elements were removed and collection was not modified.
|
|
||||||
*/
|
|
||||||
public fun <T> MutableIterable<T>.removeAll(predicate: (T) -> Boolean): Boolean = filterInPlace(predicate, true)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retains only elements of this [MutableIterable] that match the given [predicate].
|
|
||||||
*
|
|
||||||
* @return `true` if any element was removed from this collection, or `false` when all elements were retained and collection was not modified.
|
|
||||||
*/
|
|
||||||
public fun <T> MutableIterable<T>.retainAll(predicate: (T) -> Boolean): Boolean = filterInPlace(predicate, false)
|
|
||||||
|
|
||||||
private fun <T> MutableIterable<T>.filterInPlace(predicate: (T) -> Boolean, predicateResultToRemove: Boolean): Boolean {
|
|
||||||
var result = false
|
|
||||||
with(iterator()) {
|
|
||||||
while (hasNext())
|
|
||||||
if (predicate(next()) == predicateResultToRemove) {
|
|
||||||
remove()
|
|
||||||
result = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all elements from this [MutableList] that match the given [predicate].
|
|
||||||
*
|
|
||||||
* @return `true` if any element was removed from this collection, or `false` when no elements were removed and collection was not modified.
|
|
||||||
*/
|
|
||||||
public fun <T> MutableList<T>.removeAll(predicate: (T) -> Boolean): Boolean = filterInPlace(predicate, true)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retains only elements of this [MutableList] that match the given [predicate].
|
|
||||||
*
|
|
||||||
* @return `true` if any element was removed from this collection, or `false` when all elements were retained and collection was not modified.
|
|
||||||
*/
|
|
||||||
public fun <T> MutableList<T>.retainAll(predicate: (T) -> Boolean): Boolean = filterInPlace(predicate, false)
|
|
||||||
|
|
||||||
private fun <T> MutableList<T>.filterInPlace(predicate: (T) -> Boolean, predicateResultToRemove: Boolean): Boolean {
|
|
||||||
if (this !is RandomAccess)
|
|
||||||
return (this as MutableIterable<T>).filterInPlace(predicate, predicateResultToRemove)
|
|
||||||
|
|
||||||
var writeIndex: Int = 0
|
|
||||||
for (readIndex in 0..lastIndex) {
|
|
||||||
val element = this[readIndex]
|
|
||||||
if (predicate(element) == predicateResultToRemove)
|
|
||||||
continue
|
|
||||||
|
|
||||||
if (writeIndex != readIndex)
|
|
||||||
this[writeIndex] = element
|
|
||||||
|
|
||||||
writeIndex++
|
|
||||||
}
|
|
||||||
if (writeIndex < size) {
|
|
||||||
for (removeIndex in lastIndex downTo writeIndex)
|
|
||||||
removeAt(removeIndex)
|
|
||||||
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all elements from this [MutableCollection] that are also contained in the given [elements] collection.
|
* Removes all elements from this [MutableCollection] that are also contained in the given [elements] collection.
|
||||||
*/
|
*/
|
||||||
@@ -270,6 +197,117 @@ private fun MutableCollection<*>.retainNothing(): Boolean {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all elements from this [MutableIterable] that match the given [predicate].
|
||||||
|
*
|
||||||
|
* @return `true` if any element was removed from this collection, or `false` when no elements were removed and collection was not modified.
|
||||||
|
*/
|
||||||
|
public fun <T> MutableIterable<T>.removeAll(predicate: (T) -> Boolean): Boolean = filterInPlace(predicate, true)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retains only elements of this [MutableIterable] that match the given [predicate].
|
||||||
|
*
|
||||||
|
* @return `true` if any element was removed from this collection, or `false` when all elements were retained and collection was not modified.
|
||||||
|
*/
|
||||||
|
public fun <T> MutableIterable<T>.retainAll(predicate: (T) -> Boolean): Boolean = filterInPlace(predicate, false)
|
||||||
|
|
||||||
|
private fun <T> MutableIterable<T>.filterInPlace(predicate: (T) -> Boolean, predicateResultToRemove: Boolean): Boolean {
|
||||||
|
var result = false
|
||||||
|
with(iterator()) {
|
||||||
|
while (hasNext())
|
||||||
|
if (predicate(next()) == predicateResultToRemove) {
|
||||||
|
remove()
|
||||||
|
result = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new list with the elements of this list randomly shuffled
|
||||||
|
* using the specified [random] instance as the source of randomness.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
public fun <T> Iterable<T>.shuffled(random: Random): List<T> = toMutableList().apply { shuffle(random) }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the element at the specified [index] from this list.
|
||||||
|
* In Kotlin one should use the [MutableList.removeAt] function instead.
|
||||||
|
*/
|
||||||
|
@Deprecated("Use removeAt(index) instead.", ReplaceWith("removeAt(index)"), level = DeprecationLevel.ERROR)
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline fun <T> MutableList<T>.remove(index: Int): T = removeAt(index)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the first element from this mutable list and returns that removed element, or throws [NoSuchElementException] if this list is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public fun <T> MutableList<T>.removeFirst(): T = if (isEmpty()) throw NoSuchElementException("List is empty.") else removeAt(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the first element from this mutable list and returns that removed element, or returns `null` if this list is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public fun <T> MutableList<T>.removeFirstOrNull(): T? = if (isEmpty()) null else removeAt(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the last element from this mutable list and returns that removed element, or throws [NoSuchElementException] if this list is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public fun <T> MutableList<T>.removeLast(): T = if (isEmpty()) throw NoSuchElementException("List is empty.") else removeAt(lastIndex)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the last element from this mutable list and returns that removed element, or returns `null` if this list is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public fun <T> MutableList<T>.removeLastOrNull(): T? = if (isEmpty()) null else removeAt(lastIndex)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all elements from this [MutableList] that match the given [predicate].
|
||||||
|
*
|
||||||
|
* @return `true` if any element was removed from this collection, or `false` when no elements were removed and collection was not modified.
|
||||||
|
*/
|
||||||
|
public fun <T> MutableList<T>.removeAll(predicate: (T) -> Boolean): Boolean = filterInPlace(predicate, true)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retains only elements of this [MutableList] that match the given [predicate].
|
||||||
|
*
|
||||||
|
* @return `true` if any element was removed from this collection, or `false` when all elements were retained and collection was not modified.
|
||||||
|
*/
|
||||||
|
public fun <T> MutableList<T>.retainAll(predicate: (T) -> Boolean): Boolean = filterInPlace(predicate, false)
|
||||||
|
|
||||||
|
private fun <T> MutableList<T>.filterInPlace(predicate: (T) -> Boolean, predicateResultToRemove: Boolean): Boolean {
|
||||||
|
if (this !is RandomAccess)
|
||||||
|
return (this as MutableIterable<T>).filterInPlace(predicate, predicateResultToRemove)
|
||||||
|
|
||||||
|
var writeIndex: Int = 0
|
||||||
|
for (readIndex in 0..lastIndex) {
|
||||||
|
val element = this[readIndex]
|
||||||
|
if (predicate(element) == predicateResultToRemove)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if (writeIndex != readIndex)
|
||||||
|
this[writeIndex] = element
|
||||||
|
|
||||||
|
writeIndex++
|
||||||
|
}
|
||||||
|
if (writeIndex < size) {
|
||||||
|
for (removeIndex in lastIndex downTo writeIndex)
|
||||||
|
removeAt(removeIndex)
|
||||||
|
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Randomly shuffles elements in this mutable list using the specified [random] instance as the source of randomness.
|
* Randomly shuffles elements in this mutable list using the specified [random] instance as the source of randomness.
|
||||||
*
|
*
|
||||||
@@ -285,10 +323,3 @@ public fun <T> MutableList<T>.shuffle(random: Random): Unit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a new list with the elements of this list randomly shuffled
|
|
||||||
* using the specified [random] instance as the source of randomness.
|
|
||||||
*/
|
|
||||||
@SinceKotlin("1.3")
|
|
||||||
public fun <T> Iterable<T>.shuffled(random: Random): List<T> = toMutableList().apply { shuffle(random) }
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,26 @@ class MutableCollectionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test fun removeFirst() {
|
||||||
|
val list = mutableListOf("first", "second")
|
||||||
|
|
||||||
|
assertEquals("first", list.removeFirst())
|
||||||
|
assertEquals("second", list.removeFirstOrNull())
|
||||||
|
|
||||||
|
assertNull(list.removeFirstOrNull())
|
||||||
|
assertFailsWith<NoSuchElementException> { list.removeFirst() }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun removeLast() {
|
||||||
|
val list = mutableListOf("first", "second")
|
||||||
|
|
||||||
|
assertEquals("second", list.removeLast())
|
||||||
|
assertEquals("first", list.removeLastOrNull())
|
||||||
|
|
||||||
|
assertNull(list.removeLastOrNull())
|
||||||
|
assertFailsWith<NoSuchElementException> { list.removeLast() }
|
||||||
|
}
|
||||||
|
|
||||||
@Test fun removeAll() {
|
@Test fun removeAll() {
|
||||||
val content = listOf("foo", "bar", "bar")
|
val content = listOf("foo", "bar", "bar")
|
||||||
val data = listOf("bar")
|
val data = listOf("bar")
|
||||||
|
|||||||
+4
@@ -2132,6 +2132,10 @@ public final class kotlin/collections/CollectionsKt {
|
|||||||
public static final fun removeAll (Ljava/util/Collection;Lkotlin/sequences/Sequence;)Z
|
public static final fun removeAll (Ljava/util/Collection;Lkotlin/sequences/Sequence;)Z
|
||||||
public static final fun removeAll (Ljava/util/Collection;[Ljava/lang/Object;)Z
|
public static final fun removeAll (Ljava/util/Collection;[Ljava/lang/Object;)Z
|
||||||
public static final fun removeAll (Ljava/util/List;Lkotlin/jvm/functions/Function1;)Z
|
public static final fun removeAll (Ljava/util/List;Lkotlin/jvm/functions/Function1;)Z
|
||||||
|
public static final fun removeFirst (Ljava/util/List;)Ljava/lang/Object;
|
||||||
|
public static final fun removeFirstOrNull (Ljava/util/List;)Ljava/lang/Object;
|
||||||
|
public static final fun removeLast (Ljava/util/List;)Ljava/lang/Object;
|
||||||
|
public static final fun removeLastOrNull (Ljava/util/List;)Ljava/lang/Object;
|
||||||
public static final fun requireNoNulls (Ljava/lang/Iterable;)Ljava/lang/Iterable;
|
public static final fun requireNoNulls (Ljava/lang/Iterable;)Ljava/lang/Iterable;
|
||||||
public static final fun requireNoNulls (Ljava/util/List;)Ljava/util/List;
|
public static final fun requireNoNulls (Ljava/util/List;)Ljava/util/List;
|
||||||
public static final fun retainAll (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Z
|
public static final fun retainAll (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Z
|
||||||
|
|||||||
Reference in New Issue
Block a user