How to copy list in Kotlin?
I'm using
val selectedSeries = mutableListOf<String>()
selectedSeries.addAll(series)
Is there a easier way?
How to copy list in Kotlin?
I'm using
val selectedSeries = mutableListOf<String>()
selectedSeries.addAll(series)
Is there a easier way?
This works fine.
val selectedSeries = series.toMutableList()
val selectedSeries = series.toList()
also works because it calls toMutableList()
in its implementation. –
Languor ===
and have to say toList()
doesn't copy the collection, but toMutableList()
does –
Walkin Iterable.toList()
returnsemptyList()
, which always returns the same (immutable) object. So if you test with emptyList()
you'll get the same object back. –
Bakki toMutableList()
returns a new list, "Returns a new MutableList filled with all elements of this collection.". –
Heavyset .toMutable…
on it. –
Maleate You can use
List -> toList()
Array -> toArray()
ArrayList -> toArray()
MutableList -> toMutableList()
Example:
val array = arrayListOf("1", "2", "3", "4")
val arrayCopy = array.toArray() // copy array to other array
Log.i("---> array " , array?.count().toString())
Log.i("---> arrayCopy " , arrayCopy?.count().toString())
array.removeAt(0) // remove first item in array
Log.i("---> array after remove" , array?.count().toString())
Log.i("---> arrayCopy after remove" , arrayCopy?.count().toString())
print log:
array: 4
arrayCopy: 4
array after remove: 3
arrayCopy after remove: 4
array
is actually an ArrayList
while arrayCopy
is an Array
. Their names are misleading. –
Selfaggrandizement If your list is holding kotlin data class, you can do this
selectedSeries = ArrayList(series.map { it.copy() })
mutableList
, you can use selectedSeries = series.map { it.copy() }.toMutableList()
–
Kela I can come up with two alternative ways:
1. val selectedSeries = mutableListOf<String>().apply { addAll(series) }
2. val selectedSeries = mutableListOf(*series.toTypedArray())
Update: with the new Type Inference engine(opt-in in Kotlin 1.3), We can omit the generic type parameter in 1st example and have this:
1. val selectedSeries = mutableListOf().apply { addAll(series) }
FYI.The way to opt-in new Inference is kotlinc -Xnew-inference ./SourceCode.kt
for command line, or kotlin { experimental { newInference 'enable'}
for Gradle. For more info about the new Type Inference, check this video: KotlinConf 2018 - New Type Inference and Related Language Features by Svetlana Isakova, especially 'inference for builders' at 30'
List.addAll
#54381827 Use https://mcmap.net/q/116576/-how-to-clone-or-copy-a-list-in-kotlin Test it try.kotlinlang.org/#/UserProjects/pllbim18v1vfa6one4i8l0hasj/… –
Tousle Just like in Java:
List:
val list = mutableListOf("a", "b", "c")
val list2 = ArrayList(list)
Map:
val map = mutableMapOf("a" to 1, "b" to 2, "c" to 3)
val map2 = HashMap(map)
Assuming you're targeting the JVM (or Android); I'm not sure it works for other targets, as it relies on the copy constructors of ArrayList and HashMap.
You can use the provided extension Iterable.toMutableList()
which will provide you with a new list. Unfortunately, as its signature and documentation suggest, it's meant to ensure that an Iterable
is a List
(just like toString
and many other to<type>
methods). Nothing guarantees you that it's going to be a new list. For instance, adding the following line at the beginning of the extension: if (this is List) return this
is a legitimate performance improvement (if it indeed improves the performance).
Also, because of its name, the resulting code isn't very clear.
I prefer to add my own extension to be sure of the result and create a much more clear code (just like we have for arrays):
fun <T> List<T>.copyOf(): List<T> {
return mutableListOf<T>().also { it.addAll(this) }
}
fun <T> List<T>.mutableCopyOf(): MutableList<T> {
return mutableListOf<T>().also { it.addAll(this) }
}
Note that addAll
is the fastest way to copy because it uses the native System.arraycopy
in the implementation of ArrayList
.
Also, beware that this will only give you a shallow copy.
EDIT:
You might want to use the more generic version:
fun <T> Collection<T>.copyOf(): Collection<T> {
return mutableListOf<T>().also { it.addAll(this) }
}
fun <T> Collection<T>.mutableCopyOf(): MutableCollection<T> {
return mutableListOf<T>().also { it.addAll(this) }
}
addAll(this@copyOf)
, because this
inside apply
will refer to the newly created empty list? Either that or mutableListOf<T>().also { it.addAll(this) }
? –
Accouterment For a shallow copy, I suggest
.map{it}
That will work for many collection types.
Map
s. It compiles, but since the it
is a Map.Entry
, and the copy is shallow, you have the same entries. –
Flieger You can use the ArrayList
constructor: ArrayList(list)
var oldList: List<ClassA>?
val newList = oldList.map { it.copy() }
I would use the toCollection()
extension method:
val original = listOf("A", "B", "C")
val copy = original.toCollection(mutableListOf())
This will create a new MutableList
and then add each element of the original to the newly-created list.
The inferred type here will be MutableList<String>
. If you don't want to expose the mutability of this new list, you can declare the type explicitly as an immutable list:
val copy: List<String> = original.toCollection(mutableListOf())
IMHO the best and most idomatic way is use collection builders in new versions of Kotlin (1.6+)
val shallowListCopy = buildList { addAll(list) }
shallow
copy? Overview of the function and test of its behaviour shows it returns a deep
copy -- not shallow
. –
Latashalatashia shallow
copy. I wrote a test suite to confirm its behaviour. From your perspective what would you suggest as a deep
copy in the modern kotlin
? –
Latashalatashia listOf(instances).map{ it.copy() }
–
Gunyah Collection
as a member field of your data class
, .copy()
call would not make a deep
copy of this collection. Haven't verified it yet. –
Latashalatashia After trying shallow copy, deep copy cloning and many more i found this solution surely it will work for you.
val iterator: Iterator<Object> = yourList.iterator()
while (iterator.hasNext())
newList.add(iterator.next().copy())
For simple lists has many right solutions above.
However, it's just for shallows lists.
The below function works for any 2 dimensional ArrayList
. ArrayList
is, in practice, equivalent to MutableList
. Interestingly it doesn't work when using explicit MutableList
type. If one needs more dimensions, it's necessary make more functions.
fun <T>cloneMatrix(v:ArrayList<ArrayList<T>>):ArrayList<ArrayList<T>>{
var MatrResult = ArrayList<ArrayList<T>>()
for (i in v.indices) MatrResult.add(v[i].clone() as ArrayList<T>)
return MatrResult
}
Demo for integer Matrix:
var mat = arrayListOf(arrayListOf<Int>(1,2),arrayListOf<Int>(3,12))
var mat2 = ArrayList<ArrayList<Int>>()
mat2 = cloneMatrix<Int>(mat)
mat2[1][1]=5
println(mat[1][1])
it shows 12
Try below code for copying list in Kotlin
arrayList2.addAll(arrayList1.filterNotNull())
© 2022 - 2024 — McMap. All rights reserved.