val selectedSeries = series.toList()também funciona porque chama toMutableList()em sua implementação.
Flávio Faria
4
@ FlávioFaria acabou de testar com ===e tenho que dizer toList()que não copia a coleção, mas toMutableList()sim
Peppermint Paddy
3
@PeppermintPaddy Ele faz cópia, exceto no caso de listas vazias. Se a fonte estiver vazia, Iterable.toList()retorna emptyList(), que sempre retorna o mesmo objeto (imutável). Portanto, se você testar com, emptyList()obterá o mesmo objeto de volta.
Laurence Gonsalves
52
Eu pessoalmente não gosto dessa ideia ... Nada na concessão de documentos que toMutableList()deva retornar uma nova instância de uma lista se a instância que chama o método já é uma lista mutável.
BrunoJCM
4
esta não é uma boa resposta, e definitivamente não é a certa, não há garantia de que futuras implementações possam mudar, a menos que seja especificamente documentado que esta chamada de método sempre retornará uma nova cópia.
Bhargav
23
Você pode usar
Listar -> toList ()
Array -> toArray ()
ArrayList -> toArray ()
MutableList -> toMutableList ()
Exemplo:
val array = arrayListOf("1","2","3","4")val arrayCopy = array.toArray()// copy array to other arrayLog.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())
imprimir log:
array:4
arrayCopy:4
array after remove:3
arrayCopy after remove:4
Atualização: com o novo mecanismo de inferência de tipo (opcional no Kotlin 1.3), podemos omitir o parâmetro de tipo genérico no primeiro exemplo e ter este:
Para sua informação. A maneira de ativar a nova Inferência é kotlinc -Xnew-inference ./SourceCode.ktpor linha de comando ou kotlin { experimental { newInference 'enable'}para Gradle. Para obter mais informações sobre a nova inferência de tipo, confira este vídeo: KotlinConf 2018 - Nova inferência de tipo e recursos de linguagem relacionados por Svetlana Isakova , especialmente 'inferência para construtores' em 30 '
deve ser dividido em 2 respostas imho, pois acho que a primeira está correta, mas a última carece de alguma beleza.
Holger Brandl
@Jacob Wu: Fiquei surpreso ao ver que o símbolo * na segunda solução não produziu um erro. O que isso faz? Fiz uma pesquisa com "multiplicação unária" mas não encontrei nada.
Lensflare
1
@Lensflare * significa destruir uma matriz em itens separados, por exemplo, mutableListOf (* [1, 2, 3]) significa mutableListOf (1, 2, 3), é como a operação oposta a vararg
Jacob Wu
1
@Jacob Wu: Obrigado. Com sua resposta, descobri que a operadora se chama "operadora spread". Eu vejo como isso ajuda combinando alguns parâmetros com uma matriz em uma lista de varargs. Mas que benefício isso tem em seu exemplo? É mais rápido ou algo assim? Ou é a chave para garantir que a coleção seja copiada?
Lensflare
@Lensflare Acho que o benefício é apenas a sintaxe - o código é curto e nenhum tipo genérico explícito é necessário (como no meu primeiro exemplo). Nos bastidores, acredito que o código é compilado para operações de array, portanto, o desempenho deve ser o mesmo.
Você pode usar a extensão fornecida, Iterable.toMutableList()que fornecerá uma nova lista. Infelizmente, como sua assinatura e documentação sugerem, ele serve para garantir que um Iterableé um List(assim como toStringe muitos outros to<type>métodos). Nada garante que será uma lista nova . Por exemplo, adicionar a seguinte linha no início da extensão: if (this is List) return thisé uma melhoria de desempenho legítima (se de fato melhora o desempenho).
Além disso, por causa de seu nome, o código resultante não é muito claro.
Prefiro adicionar minha própria extensão para ter certeza do resultado e criar um código muito mais claro (assim como temos para matrizes ):
fun<T>List<T>.copyOf():List<T>{val original =thisreturn mutableListOf<T>().apply { addAll(original)}}fun<T>List<T>.mutableCopyOf():MutableList<T>{val original =thisreturn mutableListOf<T>().apply { addAll(original)}}
Observe que addAllé a maneira mais rápida de copiar porque usa o nativo System.arraycopyna implementação de ArrayList.
Além disso, tome cuidado, pois isso só lhe dará uma cópia superficial .
Eu gosto dessa solução. Não deveria ser addAll(this@copyOf), porque thisdentro applyvai se referir à lista vazia recém-criada? Isso ou mutableListOf<T>().also { it.addAll(this) }?
Observe que não funciona para Maps. Ele compila, mas como ité um Map.Entrye a cópia é superficial, você tem as mesmas entradas.
noamtm
1
@noamtm sim, é isso que quero dizer com cópia superficial. Este método nunca copiará as entradas. Só fará uma cópia da coleção com as mesmas entradas. O mapa não é nada especial aqui.
Lensflare de
2
Meu ponto é que, embora seja tentador usá-lo em mapas também, e ele compila e parece funcionar - ele realmente não funciona.
noamtm de
4
Assim como em Java:
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)
Supondo que você esteja visando o JVM (ou Android); Não tenho certeza se funciona para outros destinos, pois se baseia nos construtores de cópia de ArrayList e HashMap.
val original = listOf("A","B","C")val copy = original.toCollection(mutableListOf())
Isso criará um novo MutableListe, em seguida, adicionará cada elemento do original à lista recém-criada.
O tipo inferido aqui será MutableList<String>. Se você não quiser expor a mutabilidade dessa nova lista, pode declarar o tipo explicitamente como uma lista imutável:
val copy:List<String>= original.toCollection(mutableListOf())
Para listas simples, há muitas soluções corretas acima.
No entanto, é apenas para listas rasas.
A função abaixo funciona para qualquer bidimensional ArrayList. ArrayListé, na prática, equivalente a MutableList. Curiosamente, não funciona ao usar um MutableListtipo explícito . Se alguém precisa de mais dimensões, é necessário fazer mais funções.
fun<T>cloneMatrix(v:ArrayList<ArrayList<T>>):ArrayList<ArrayList<T>>{varMatrResult=ArrayList<ArrayList<T>>()for(i in v.indices)MatrResult.add(v[i].clone()asArrayList<T>)returnMatrResult}
Demonstração para matriz inteira:
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])
Respostas:
Isso funciona bem.
fonte
val selectedSeries = series.toList()
também funciona porque chamatoMutableList()
em sua implementação.===
e tenho que dizertoList()
que não copia a coleção, mastoMutableList()
simIterable.toList()
retornaemptyList()
, que sempre retorna o mesmo objeto (imutável). Portanto, se você testar com,emptyList()
obterá o mesmo objeto de volta.toMutableList()
deva retornar uma nova instância de uma lista se a instância que chama o método já é uma lista mutável.Você pode usar
Listar -> toList ()
Array -> toArray ()
ArrayList -> toArray ()
MutableList -> toMutableList ()
Exemplo:
imprimir log:
fonte
Posso propor duas maneiras alternativas:
Atualização: com o novo mecanismo de inferência de tipo (opcional no Kotlin 1.3), podemos omitir o parâmetro de tipo genérico no primeiro exemplo e ter este:
Para sua informação. A maneira de ativar a nova Inferência é
kotlinc -Xnew-inference ./SourceCode.kt
por linha de comando oukotlin { experimental { newInference 'enable'}
para Gradle. Para obter mais informações sobre a nova inferência de tipo, confira este vídeo: KotlinConf 2018 - Nova inferência de tipo e recursos de linguagem relacionados por Svetlana Isakova , especialmente 'inferência para construtores' em 30 'fonte
Se sua lista contém classes de dados kotlin , você pode fazer isso
fonte
Você pode usar a extensão fornecida,
Iterable.toMutableList()
que fornecerá uma nova lista. Infelizmente, como sua assinatura e documentação sugerem, ele serve para garantir que umIterable
é umList
(assim comotoString
e muitos outrosto<type>
métodos). Nada garante que será uma lista nova . Por exemplo, adicionar a seguinte linha no início da extensão:if (this is List) return this
é uma melhoria de desempenho legítima (se de fato melhora o desempenho).Além disso, por causa de seu nome, o código resultante não é muito claro.
Prefiro adicionar minha própria extensão para ter certeza do resultado e criar um código muito mais claro (assim como temos para matrizes ):
Observe que
addAll
é a maneira mais rápida de copiar porque usa o nativoSystem.arraycopy
na implementação deArrayList
.Além disso, tome cuidado, pois isso só lhe dará uma cópia superficial .
fonte
addAll(this@copyOf)
, porquethis
dentroapply
vai se referir à lista vazia recém-criada? Isso oumutableListOf<T>().also { it.addAll(this) }
?Para uma cópia superficial, sugiro
Isso funcionará para muitos tipos de coleção.
fonte
Map
s. Ele compila, mas comoit
é umMap.Entry
e a cópia é superficial, você tem as mesmas entradas.Assim como em Java:
Lista:
Mapa:
Supondo que você esteja visando o JVM (ou Android); Não tenho certeza se funciona para outros destinos, pois se baseia nos construtores de cópia de ArrayList e HashMap.
fonte
Eu usaria o
toCollection()
método de extensão :Isso criará um novo
MutableList
e, em seguida, adicionará cada elemento do original à lista recém-criada.O tipo inferido aqui será
MutableList<String>
. Se você não quiser expor a mutabilidade dessa nova lista, pode declarar o tipo explicitamente como uma lista imutável:fonte
Para listas simples, há muitas soluções corretas acima.
No entanto, é apenas para listas rasas.
A função abaixo funciona para qualquer bidimensional
ArrayList
.ArrayList
é, na prática, equivalente aMutableList
. Curiosamente, não funciona ao usar umMutableList
tipo explícito . Se alguém precisa de mais dimensões, é necessário fazer mais funções.Demonstração para matriz inteira:
isto mostra
12
fonte
Você pode usar o
ArrayList
construtor:ArrayList(list)
fonte
Experimente o código abaixo para copiar a lista em Kotlin
fonte