Diferença entre os tipos Lista e Matriz no Kotlin

192

Qual é a diferença entre Liste Arraytypes?
Parece que pode fazer as mesmas operações com eles (loops, expressão de filtro, etc.), existe alguma diferença de comportamento ou uso?

val names1 = listOf("Joe","Ben","Thomas")
val names2 = arrayOf("Joe","Ben","Thomas")

for (name in names1)
    println(name)
for (name in names2)
    println(name)
Daniel Hári
fonte

Respostas:

281

Matrizes e listas (representadas por List<T>e seu subtipo MutableList<T>) têm muitas diferenças, eis as mais significativas:

  • Array<T>é uma classe com implementação conhecida: é uma região seqüencial de memória de tamanho fixo que armazena os itens (e na JVM é representada pela matriz Java ).

    List<T>e MutableList<T>são interfaces que têm diferentes implementações: ArrayList<T>, LinkedList<T>etc. representação de memória e operações de lógica de listas são definidos na implementação concreta, por exemplo, a indexação num LinkedList<T>atravessa as ligações e leva tempo O (n), enquanto ArrayList<T>lojas de seus itens em uma matriz alocada dinamicamente.

    val list1: List<Int> = LinkedList<Int>()
    val list2: List<Int> = ArrayList<Int>()
  • Array<T>é mutável (pode ser alterado por qualquer referência a ele), mas List<T>não possui métodos de modificação (é uma exibição somente leituraMutableList<T> ou uma implementação de lista imutável ).

    val a = arrayOf(1, 2, 3)
    a[0] = a[1] // OK
    
    val l = listOf(1, 2, 3)
    l[0] = l[1] // doesn't compile
    
    val m = mutableListOf(1, 2, 3)
    m[0] = m[1] // OK
  • As matrizes têm tamanho fixo e não podem expandir ou reduzir a identidade de retenção (é necessário copiar uma matriz para redimensioná-la). Quanto às listas, MutableList<T>tem adde removefunções, para que ele possa aumentar e reduzir seu tamanho.

    val a = arrayOf(1, 2, 3)
    println(a.size) // will always be 3 for this array
    
    val l = mutableListOf(1, 2, 3)
    l.add(4)
    println(l.size) // 4
  • Array<T>é invariável emT ( Array<Int>não é Array<Number>), o mesmo para MutableList<T>, mas List<T>é covariante ( List<Int>é List<Number>).

    val a: Array<Number> = Array<Int>(0) { 0 } // won't compile
    val l: List<Number> = listOf(1, 2, 3) // OK
  • As matrizes são optimizados para primitivas: existem separada IntArray, DoubleArray, CharArrayetc, que são mapeados para Java matrizes primitivas ( int[], double[], char[]), não embalados uns ( Array<Int>é mapeado para Java da Integer[]). As listas em geral não têm implementações otimizadas para primitivas, embora algumas bibliotecas (fora do JDK) forneçam listas otimizadas por primitivas.

  • List<T>e MutableList<T>são tipos mapeados e têm comportamento especial na interoperabilidade Java (o Java List<T>é visto no Kotlin como um List<T>ou MutableList<T>). As matrizes também são mapeadas, mas possuem outras regras de interoperabilidade Java.

  • Certos tipos de matriz são usados ​​em anotações (matrizes primitivas Array<String>, e matrizes com enum classentradas), e há uma sintaxe literal de matriz especial para anotações . Listas e outras coleções não podem ser usadas em anotações.

  • Quanto ao uso, a boa prática é preferir usar listas em vez de matrizes em todos os lugares, exceto em partes críticas do desempenho do código, o raciocínio é o mesmo do Java .

tecla de atalho
fonte
26

A principal diferença do lado do uso é que as matrizes têm um tamanho fixo enquanto (Mutable)Listpodem ajustar seu tamanho dinamicamente. Além disso, Arrayé mutável, enquanto Listnão é.

Além disso, kotlin.collections.Listé uma interface implementada entre outros por java.util.ArrayList. Também é estendido kotlin.collections.MutableListpara ser usado quando são necessárias coleções que permitam a modificação de itens.

No nível da jvm Arrayé representado por matrizes . Listpor outro lado, é representado por, java.util.Listuma vez que não há equivalentes imutáveis ​​de coleções disponíveis em Java.

miensol
fonte
Não estou totalmente convencido aqui. O que é mutável Array? Apenas são elementos - o mesmo no List. O tamanho de Listtambém é fixo.
AndroidEx 28/03
1
@AndroidEx, o seguinte será compilado, val intArray = arrayOf(1,2,3); intArray[0] = 2enquanto isso não acontecerá val intList = listOf(1,2,3); intList[0] = 2. O de Listfato tem um tamanho fixo, mas o MutableListque o estende não é, portanto, é possível que um val a:List<Int>relatório seja diferente sizenas chamadas subseqüentes.
28516 miensol
É recomendável usar Listou ArrayList?
IgorGanapolsky
2
@IgorGanapolsky Se você não se importa com o uso concreto da implementação List(provavelmente 99% dos casos). Se você se preocupam com o uso de implementação ArrayListou LinkedListou qualquer outra aplicação concreta.
miensol