web-dev-qa-db-fra.com

Comment filtrer une liste en place avec Kotlin?

Dans Java je peux supprimer des éléments d'une liste avec ce code:

private void filterList(List<Item> items) {
    Iterator<Item> iterator = items.iterator();
    while (iterator.hasNext()) {
        if (checkItem(iterator.next())) {
            iterator.remove();
        }
    }
}

Comment faire la même chose dans Kotlin (c'est-à-dire supprimer certains éléments dans un List sans recréation)?

19
BArtWell

Utilisez simplement .retainAll { ... } ou .removeAll { ... } , tous deux acceptant un prédicat, pour le filtrer sur place:

items.retainAll { shouldRetain(it) }
items.removeAll { shouldRemove(it) }

Notez que items doit être un MutableList<T> pour cela, pas seulement List<T>, qui est une liste en lecture seule dans Kotlin et n'expose donc aucune fonction de mutation (voir: Collections in la référence de la langue).

Soit dit en passant, ces deux fonctions sont mises en œuvre efficacement pour les listes qui prennent en charge l'accès aléatoire: alors la liste n'est pas compactée après la suppression de chaque élément ( O (n2) le pire des cas), et à la place, les éléments sont déplacés dans la liste au fur et à mesure de leur traitement, donnant O (n) temps.


Et si vous ne souhaitez pas modifier la liste d'origine, vous pouvez produire une collection séparée avec uniquement les éléments que vous souhaitez conserver à l'aide de .filter { ... } ou .filterNot { ... } , cela fonctionnera pour la lecture seule List<T> ainsi que:

val filtered = items.filter { shouldRetain(it) }
val filtered = items.filterNot { shouldRemove(it) }
43
hotkey

Kotlin a beaucoup de fonctions intégrées soignées. Vous pouvez essayer d'utiliser filter ici.

val filteredItems = items.filter { checkItem(it) }  

Malheureusement, il recréera la liste. Cette API a été conçue exprès pour éviter une mutabilité supplémentaire.

Mais si vous souhaitez continuer avec une méthode MutableList, utilisez la méthode retainAll

items.retainAll { checkItem(it) }
4

Cela supprimera les nombres pairs de la liste 1-9 et imprime [1, 3, 5, 7, 9]

var myLists = mutableListOf(1,2,3,4,5,6,7,8,9)
myLists.removeAll{ it % 2 == 0 }
println(myLists)

Cela conservera les nombres pairs et supprimera les autres de la liste 1-9, et imprime [2, 4, 6, 8]

myLists = mutableListOf(1,2,3,4,5,6,7,8,9)
myLists.retainAll{ it % 2 == 0 }
println(myLists)

Essayez-les dans https://play.kotlinlang.org/

0
s-hunter