242 votes

Il manque "add" et "remove" à List de Kotlin, "put" à Map, etc ?

En Java, nous pourrions faire ce qui suit

public class TempClass {
    List<Integer> myList = null;
    void doSomething() {
        myList = new ArrayList<>();
        myList.add(10);
        myList.remove(10);
    }
}

Mais si nous le réécrivons directement en Kotlin comme ci-dessous

class TempClass {
    var myList: List<Int>? = null
    fun doSomething() {
        myList = ArrayList<Int>()
        myList!!.add(10)
        myList!!.remove(10)
    }
}

J'ai eu l'erreur de ne pas trouver add y remove de ma liste

Je contourne le casting en ArrayList, mais c'est bizarre d'avoir à le faire, alors qu'en Java le casting n'est pas nécessaire. Et cela va à l'encontre de l'objectif de la classe abstraite List.

class TempClass {
    var myList: List<Int>? = null
    fun doSomething() {
        myList = ArrayList<Int>()
        (myList!! as ArrayList).add(10)
        (myList!! as ArrayList).remove(10)
    }
}

Existe-t-il un moyen d'utiliser une liste sans avoir à la couler, comme cela pourrait être fait en Java ?

1 votes

Juste un commentaire sur la raison pour laquelle vous ne pouvez pas faire myList = null et puis plus tard appeler ajouter sans !! . Vous pouvez contourner ce problème en utilisant l'option lateinit mot-clé devant votre propriété comme ceci : lateinit var myList: List<Int> De cette façon, vous n'aurez pas besoin d'initialiser la liste immédiatement, mais vous garantissez au compilateur que vous l'initialiserez avant d'utiliser la liste la première fois. C'est une solution plus souple, mais elle vous impose une responsabilité en tant que développeur.

429voto

gotnull Points 4918

Contrairement à de nombreux langages, Kotlin fait la distinction entre les collections mutables et immuables (listes, ensembles, cartes, etc.). Un contrôle précis du moment exact où les collections peuvent être modifiées est utile pour éliminer les bogues et pour concevoir de bonnes API.

https://kotlinlang.org/docs/reference/collections.html

Vous devrez utiliser un MutableList liste.

class TempClass {
    var myList: MutableList<Int> = mutableListOf<Int>()
    fun doSomething() {
        // myList = ArrayList<Int>() // initializer is redundant
        myList.add(10)
        myList.remove(10)
    }
}

MutableList<Int> = arrayListOf() devrait également fonctionner.

5 votes

Réponse agréable et bien écrite. Je choisis la vôtre comme réponse modèle bien que la mienne se trouve en dessous :)

6 votes

Vous n'avez pas besoin de rendre la liste nullable si vous l'initialisez immédiatement. J'ai modifié votre réponse.

42voto

Lukas Points 1433

Définir une collection de listes en Kotlin de différentes manières :

  • Variable immuable avec liste immuable (en lecture seule) :

    val users: List<User> = listOf( User("Tom", 32), User("John", 64) )
  • Variable immuable avec liste mutable :

    val users: MutableList<User> = mutableListOf( User("Tom", 32), User("John", 64) )

    ou sans valeur initiale - liste vide et sans type de variable explicite :

    val users = mutableListOf<User>()
    //or
    val users = ArrayList<User>()
    • vous pouvez ajouter des éléments à la liste :
      • users.add(anohterUser) o
      • users += anotherUser (sous le capot, c'est users.add(anohterUser) )
  • Variable mutable avec liste immuable :

    var users: List<User> = listOf( User("Tom", 32), User("John", 64) )

    ou sans valeur initiale - liste vide et sans type de variable explicite :

    var users = emptyList<User>()
    • REMARQUE : vous pouvez ajouter* des éléments à la liste :
      • users += anotherUser - *il crée une nouvelle ArrayList et l'assigne à users
  • Variable mutable avec liste mutable :

    var users: MutableList<User> = mutableListOf( User("Tom", 32), User("John", 64) )

    ou sans valeur initiale - liste vide et sans type de variable explicite :

    var users = emptyList<User>().toMutableList()
    //or
    var users = ArrayList<User>()
    • NOTE : vous pouvez ajouter des éléments à la liste :

      • users.add(anohterUser)
      • mais sans utiliser users += anotherUser

        Erreur : Kotlin : Ambiguïté des opérateurs d'assignation :
        public fun opérateur Collection.plus(element : String) : Liste définie dans kotlin.collections
        @InlineOnly public inline operator fun MutableCollection.plusAssign(element : String) : Unité définie dans kotlin.collections

voir aussi : https://kotlinlang.org/docs/reference/collections.html

13voto

dinesh salve Points 41

Je suis d'accord avec toutes les réponses ci-dessus concernant l'utilisation de MutableList, mais vous pouvez également ajouter/supprimer des éléments de la liste et obtenir une nouvelle liste comme ci-dessous.

val newListWithElement = existingList + listOf(element)
val newListMinusElement = existingList - listOf(element)

O

val newListWithElement = existingList.plus(element)
val newListMinusElement = existingList.minus(element)

11voto

Elye Points 7892

Apparemment, la liste par défaut de Kotlin est immuable. Pour avoir une liste qui peut changer, il faut utiliser MutableList comme ci-dessous

class TempClass {
    var myList: MutableList<Int>? = null
    fun doSomething() {
        myList = ArrayList<Int>()
        myList!!.add(10)
        myList!!.remove(10)
    }
}

Mise à jour de Néanmoins, il n'est pas recommandé d'utiliser MutableList, sauf pour une liste que l'on souhaite vraiment modifier. Se réfère à https://hackernoon.com/read-only-collection-in-kotlin-leads-to-better-coding-40cdfa4c6359 pour savoir comment la collecte en lecture seule permet un meilleur codage.

0 votes

Vous avez raison d'utiliser MutableList mais l'initialiser avec null ne fonctionneront pas. Seuls les appels assertifs sûrs ou non nuls sont autorisés sur un récepteur nullable de type MutableList<Int> .

0 votes

Cela fonctionne de mon côté, et aucune erreur n'a été trouvée. Je n'ai pas besoin de l'initialiser sauf quand j'en ai besoin quand doSomething

0 votes

@Elye Je sais que c'est une vieille réponse et question, mais en utilisant lateinit au lieu de rendre la liste nullable est la bonne façon de procéder. Je ne me souviens pas si lateinit a été ajouté dès le début de Kotlin, mais c'est définitivement la solution pour l'utiliser aujourd'hui :-)

3voto

sgrover Points 31

https://kotlinlang.org/docs/reference/collections.html

Selon le lien ci-dessus, List<E> est immuable en Kotlin. Cependant, ceci pourrait fonctionner :

var list2 = ArrayList<String>()
list2.removeAt(1)

0 votes

Cela signifie que list2 est une liste mutable, voir stackoverflow.com/questions/43114367/ .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X