Kotlin'in Listesi eksik “ekle”, “kaldır”, Harita eksik “koy” vb.?


200

Java ile aşağıdakileri yapabiliriz

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

Ama eğer doğrudan aşağıdaki gibi Kotlin'e yeniden yazarsak

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

Listemden bulma addve removeişlev görmeme hatasını aldım

ArrayList için döküm etrafında çalışıyorum, ancak Java döküm gerekli değil iken, döküm için garip. Ve bu soyut sınıf Listeye sahip olma amacını yener

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

List'i kullanmamın, ancak Java'da yapılabilecekler gibi yayınlamaya gerek duymamın bir yolu var mı?


1
Sadece neden yapamadığınıza myList = nullve daha sonra çağrı ekleme olmadan bir yorum yapın !!. Bunu lateinit, mülkünüzün önündeki anahtar kelimeyi şu şekilde kullanarak üstesinden gelebilirsiniz : lateinit var myList: List<Int>bu şekilde listeyi hemen başlatmanız gerekmez, ancak listeyi ilk kez kullanmadan önce derleyiciye başlatacağınızı garanti edersiniz. Daha akıcı bir çözüm, ancak geliştirici olarak size bir sorumluluk yüklüyor.
Darwind

Yanıtlar:


355

Birçok dilden farklı olarak, Kotlin değişebilir ve değişmez koleksiyonlar (listeler, kümeler, haritalar vb.) Arasında ayrım yapar. Koleksiyonların tam olarak ne zaman düzenlenebileceği üzerinde kesin kontrol, hataları ortadan kaldırmak ve iyi API'ler tasarlamak için yararlıdır.

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

Bir MutableListliste kullanmanız gerekecek .

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() ayrıca çalışması gerekir.


4
Güzel ve iyi yazılmış cevap. Aşağıda benimkine rağmen model cevap olarak seninkini
seçiyorum

6
Listeyi hemen başlatırsanız listeyi boş bırakmanız gerekmez. Cevabınızı düzenledim.
Kirill Rakhman

37

Kotlin'de bir liste koleksiyonunu farklı şekillerde tanımlama:

  • Değişmez (salt okunur) listeye sahip değişmez değişken:

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


  • Değişken listeli değişken değişken:

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

    veya başlangıç ​​değeri olmadan - boş liste ve açık değişken türü olmadan:

    val users = mutableListOf<User>()
    //or
    val users = ArrayList<User>()
    • listeye öğe ekleyebilirsiniz:
      • users.add(anohterUser) veya
      • users += anotherUser(kaputun altında users.add(anohterUser))


  • Değişmez listeli değişken değişken:

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

    veya başlangıç ​​değeri olmadan - boş liste ve açık değişken türü olmadan:

    var users = emptyList<User>()
    • NOT: listeye * öğe ekleyebilirsiniz:
      • users += anotherUser - * yeni ArrayList oluşturur ve users


  • Değişken listeli değişken değişken:

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

    veya başlangıç ​​değeri olmadan - boş liste ve açık değişken türü olmadan:

    var users = emptyList<User>().toMutableList()
    //or
    var users = ArrayList<User>()
    • NOT: listeye öğe ekleyebilirsiniz:
      • users.add(anohterUser)
      • ama kullanmıyor users += anotherUser

        Hata: Kotlin: Atama operatörleri belirsizliği:
        public operator fun Collection.plus (element: String): Kotlin.collections içinde tanımlanan liste
        @InlineOnly public inline operator fun MutableCollection.plusAssign (element: String): kotlin.collections içinde tanımlanan birim


ayrıca bkz: https://kotlinlang.org/docs/reference/collections.html


9

MutableList'i kullanmanın yukarıdaki tüm cevaplarını kabul edin, ancak Listeye ekleyebilir / Listeden çıkarabilir ve aşağıdaki gibi yeni bir liste alabilirsiniz.

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

Veya

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

8

Görünüşe göre, varsayılan Kotlin Listesi değişmez. Değişebilecek bir Listeye sahip olmak için MutableList'i aşağıdaki gibi kullanmalısınız

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

Güncelleme Bununla birlikte, eğer gerçekten değişime istediğiniz listesi için sürece MutableList kullanmak tavsiye edilmez. Salt okunur koleksiyonun nasıl daha iyi kodlama sağladığı için https://hackernoon.com/read-only-collection-in-kotlin-leads-to-better-coding-40cdfa4c6359 anlamına gelir .


Kullanmak konusunda haklısınız MutableList, ancak ile başlatmak nullişe yaramaz. Sıfırlanabilir türdeki bir alıcıda yalnızca güvenli veya boş olmayan çağrılara izin verilir MutableList<Int>.
Fulvio

Sonumda çalışıyor ve hata bulunamadı. Ne zaman ihtiyacım olmadığı sürece başlatmaya ihtiyacım yokdoSomething
Elye

@Elye Bunun eski bir cevap ve soru olduğunu biliyorum, ancak listeyi geçersiz kılmak lateinityerine kullanmak, bu sorunla başa çıkmanın doğru yoludur. lateinitYine de Kotlin'in başından beri eklenip eklenmediğini hatırlamıyorum , ama bu bugünlerde kullanmak için kesinlikle çözüm :-)
Darwind

5

Kotlin'de MutableListveya kullanmak zorundasınız ArrayList.

Bakalım MutableListçalışma yöntemleri :

var listNumbers: MutableList<Int> = mutableListOf(10, 15, 20)
// Result: 10, 15, 20

listNumbers.add(1000)
// Result: 10, 15, 20, 1000

listNumbers.add(1, 250)
// Result: 10, 250, 15, 20, 1000

listNumbers.removeAt(0)
// Result: 250, 15, 20, 1000

listNumbers.remove(20)
// Result: 250, 15, 1000

for (i in listNumbers) { 
    println(i) 
}

Bakalım ArrayListçalışma yöntemleri :

var arrayNumbers: ArrayList<Int> = arrayListOf(1, 2, 3, 4, 5)
// Result: 1, 2, 3, 4, 5

arrayNumbers.add(20)
// Result: 1, 2, 3, 4, 5, 20

arrayNumbers.remove(1)
// Result: 2, 3, 4, 5, 20

arrayNumbers.clear()
// Result: Empty

for (j in arrayNumbers) { 
    println(j) 
}

4

Bunun gibi yeni bir tane oluşturmakla yapabilirsiniz.

var list1 = ArrayList<Int>()
var list2  = list1.toMutableList()
list2.add(item)

Şimdi list2'yi kullanabilirsiniz, teşekkür ederim.



2

Değişebilirliği İnşaatçılarla Sınırlamak

Buradaki en iyi cevaplar Kotlin'deki salt okunur arasındaki farktan bahsediyor List(NOT: salt okunur, "değişmez" değil ) ve MutableList.

Genel olarak, salt okunur listeleri kullanmak için çaba gösterilmelidir, ancak mutasyon, inşaat zamanında, özellikle de işlevsel olmayan arayüzlere sahip üçüncü taraf kütüphanelerle uğraşırken hala yararlıdır . listOfDoğrudan kullanma veya benzer bir işlevsel yapıyı foldveya reduceaşağıdaki gibi basit bir "oluşturucu işlevi" yapısını uygulama gibi alternatif yapım tekniklerinin kullanılamadığı durumlar için, geçici olarak değiştirilebilir bir listeden salt okunur bir liste oluşturur:

val readonlyList = mutableListOf<...>().apply {
  // manipulate your list here using whatever logic you need
  // the `apply` function sets `this` to the `MutableList`
  add(foo1)
  addAll(foos)
  // etc.
}.toList()

ve bu, yeniden kullanılabilir bir satır içi yardımcı program işlevine güzelce kapsüllenebilir:

inline fun <T> buildList(block: MutableList<T>.() -> Unit) = 
  mutableListOf<T>().apply(block).toList()

bu şekilde adlandırılabilir:

val readonlyList = buildList<String> {
  add("foo")
  add("bar")
}

Şimdi, tüm değiştirilebilirlik salt okunur listenin oluşturulması için kullanılan bir blok kapsamına ayrılmıştır ve kodunuzun geri kalanı oluşturucudan çıkan salt okunur listeyi kullanır.

UPDATE : KOTLIN 1.3.70 itibariyle tam buildListyukarıda fonksiyonu mevcut olan analogları ile birlikte, deneysel fonksiyonu olarak standart kütüphanesinde buildSetve buildMap. Bkz. Https://blog.jetbrains.com/kotlin/2020/03/kotlin-1-3-70-released/ .


teşekkürler ve uygulama yöntemi içinde iş mantığı ile iyi çalıştı, hatta .appy {} içinde başka birList.ForEach {add (foo)} kullandı
BENN1TH

1

Değişmez veriler kavramında, belki de bu daha iyi bir yoldur:

class TempClass {
    val list: List<Int> by lazy {
        listOf<Int>()
    }
    fun doSomething() {
        list += 10
        list -= 10
    }
}

1

Bir listolan immutabletarafından Defaultkullanabileceğiniz, ArrayListbunun yerine. bunun gibi :

 val orders = arrayListOf<String>()

o zaman add/deleteaşağıdaki gibi öğeleri yapabilirsiniz :

orders.add("Item 1")
orders.add("Item 2")

varsayılan olarak ArrayList, mutableüzerindeki işlemleri gerçekleştirebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.