Odpowiedzi:
To działa dobrze.
val selectedSeries = series.toMutableList()
val selectedSeries = series.toList()działa również, ponieważ wzywa toMutableList()do jego wykonania.
===i muszę powiedzieć, toList()że nie kopiuje kolekcji, ale toMutableList()robi
Iterable.toList()zwraca emptyList(), która zawsze zwraca ten sam (niezmienny) obiekt. Więc jeśli przeprowadzisz test emptyList(), otrzymasz z powrotem ten sam obiekt.
toMutableList()powinno zwracać nowej instancji listy, jeśli instancja wywołująca metodę jest już listą modyfikowalną.
Możesz użyć
Lista -> toList ()
Array -> toArray ()
ArrayList -> toArray ()
MutableList -> toMutableList ()
Przykład:
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())
drukuj dziennik:
array: 4
arrayCopy: 4
array after remove: 3
arrayCopy after remove: 4
Mogę wymyślić dwa alternatywne sposoby:
1. val selectedSeries = mutableListOf<String>().apply { addAll(series) }
2. val selectedSeries = mutableListOf(*series.toTypedArray())
Aktualizacja: dzięki nowemu silnikowi wnioskowania o typie (opt-in w Kotlin 1.3) możemy pominąć ogólny parametr typu w pierwszym przykładzie i mieć to:
1. val selectedSeries = mutableListOf().apply { addAll(series) }
FYI. Sposobem na włączenie nowego wnioskowania jest użycie kotlinc -Xnew-inference ./SourceCode.ktwiersza poleceń lub kotlin { experimental { newInference 'enable'}Gradle. Aby uzyskać więcej informacji na temat nowego wnioskowania o typie, obejrzyj ten film: KotlinConf 2018 - Nowe wnioskowanie o typie i powiązane funkcje językowe autorstwa Svetlany Isakovej , zwłaszcza `` wnioskowanie dla budowniczych '' w wieku 30 lat
Jeśli twoja lista zawiera klasę danych kotlin , możesz to zrobić
selectedSeries = ArrayList(series.map { it.copy() })
Możesz skorzystać z podanego rozszerzenia, Iterable.toMutableList()które zapewni Ci nową listę. Niestety, jak sugeruje jego podpis i dokumentacja , ma to na celu zapewnienie, że an Iterablejest List(podobnie jak toStringi wiele innych to<type>metod). Nic nie gwarantuje, że będzie to nowa lista. Na przykład dodanie następującego wiersza na początku rozszerzenia: if (this is List) return thisjest uzasadnioną poprawą wydajności (jeśli rzeczywiście poprawia wydajność).
Ponadto ze względu na nazwę otrzymany kod nie jest zbyt jasny.
Wolę dodać własne rozszerzenie, aby mieć pewność wyniku i stworzyć znacznie bardziej przejrzysty kod (tak jak w przypadku tablic ):
fun <T> List<T>.copyOf(): List<T> {
val original = this
return mutableListOf<T>().apply { addAll(original) }
}
fun <T> List<T>.mutableCopyOf(): MutableList<T> {
val original = this
return mutableListOf<T>().apply { addAll(original) }
}
Zauważ, że addAlljest to najszybszy sposób kopiowania, ponieważ używa natywnego System.arraycopyw implementacji ArrayList.
Uważaj również, że da ci to tylko płytką kopię .
addAll(this@copyOf), bo thiswewnątrz applybędzie odnosić się do nowo utworzonej pustej listy? Albo to, albo mutableListOf<T>().also { it.addAll(this) }?
Sugeruję, aby uzyskać płytką kopię
.map{it}
To zadziała w przypadku wielu typów kolekcji.
Maps. Kompiluje się, ale ponieważ itjest a Map.Entry, a kopia jest płytka, masz te same wpisy.
Podobnie jak w Javie:
Lista:
val list = mutableListOf("a", "b", "c")
val list2 = ArrayList(list)
Mapa:
val map = mutableMapOf("a" to 1, "b" to 2, "c" to 3)
val map2 = HashMap(map)
Zakładając, że celujesz w JVM (lub Android); Nie jestem pewien, czy działa dla innych celów, ponieważ opiera się na konstruktorach kopiujących ArrayList i HashMap.
Chciałbym skorzystać z toCollection()metody rozszerzenie :
val original = listOf("A", "B", "C")
val copy = original.toCollection(mutableListOf())
Spowoduje to utworzenie nowego, MutableLista następnie dodanie każdego elementu oryginału do nowo utworzonej listy.
Wywnioskowanym typem będzie tutaj MutableList<String>. Jeśli nie chcesz ujawniać zmienności tej nowej listy, możesz jawnie zadeklarować typ jako niezmienną listę:
val copy: List<String> = original.toCollection(mutableListOf())
Dla prostych list ma wiele poprawnych rozwiązań powyżej.
Jednak jest to tylko dla płytkich list.
Poniższa funkcja działa dla wszystkich dwuwymiarowych ArrayList. ArrayListjest w praktyce odpowiednikiem MutableList. Co ciekawe, nie działa przy użyciu MutableListtypu jawnego . Jeśli potrzeba więcej wymiarów, konieczne jest wykonanie większej liczby funkcji.
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 dla Matrix liczb całkowitych:
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])
to pokazuje 12
Możesz użyć ArrayListkonstruktora:ArrayList(list)