Kotlinのリストに「追加」、「削除」、「欠けているマップ」などがありませんか?


197

Javaでは、次のことができます

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

しかし、以下のようにKotlinに直接書き換えると

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

リストから検索addおよびremove機能しないというエラーが発生しました

私はそれをArrayListにキャストすることを回避しますが、それをキャストする必要があるのは奇妙ですが、Javaではキャストは必要ありません。そして、それは抽象クラスListを持つ目的を無効にします

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

Javaで実行できるような、Listを使用する方法をキャストする必要がない方法はありますか?


1
なぜあなたができないのかについてのコメントmyList = nullと、その後の呼び出しなしでの追加なし!!lateinitプロパティの前で次のようにキーワードを使用することで、これを克服できます。これによりlateinit var myList: List<Int>、リストをすぐに初期化する必要はありませんが、リストを初めて使用する前に初期化することをコンパイラに保証できます。これはよりスムーズなソリューションですが、開発者としての責任があります。
Darwind

回答:


351

多くの言語とは異なり、Kotlinは変更可能なコレクションと不変のコレクション(リスト、セット、マップなど)を区別します。コレクションをいつ編集できるかを正確に制御することは、バグを排除し、優れたAPIを設計するのに役立ちます。

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

MutableListリストを使用する必要があります。

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() も動作するはずです。


4
よく書かれた答え。私は以下のものを持っているにもかかわらず、モデルの回答としてあなたのものを選びます:)
Elye

6
すぐに初期化する場合は、リストをnullにできるようにする必要はありません。回答を編集しました。
Kirill Rakhman

37

Kotlinでさまざまな方法でリストコレクションを定義する:

  • 不変(読み取り専用)リストを持つ不変変数:

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


  • 可変リストを持つ不変変数:

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

    または初期値なし-空のリストと明示的な変数タイプなし:

    val users = mutableListOf<User>()
    //or
    val users = ArrayList<User>()
    • リストにアイテムを追加できます:
      • users.add(anohterUser) または
      • users += anotherUser(ボンネットの下にありますusers.add(anohterUser)


  • 不変リスト付きの可変変数:

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

    または初期値なし-空のリストと明示的な変数タイプなし:

    var users = emptyList<User>()
    • 注:リストにアイテムを追加できます*。
      • users += anotherUser -*それは新しいArrayListを作成し、それを users


  • 可変リスト付きの可変変数:

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

    または初期値なし-空のリストと明示的な変数タイプなし:

    var users = emptyList<User>().toMutableList()
    //or
    var users = ArrayList<User>()
    • 注:リストにアイテムを追加できます。
      • users.add(anohterUser)
      • しかし、使用していません users += anotherUser

        エラー:Kotlin:代入演算子のあいまいさ:
        パブリック演算子fun Collection.plus(element:String):kotlin.collectionsで定義されたリスト
        @InlineOnlyパブリックインライン演算子fun MutableCollection.plusAssign(element:String):kotlin.collectionsで定義されたユニット


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


9

MutableListの使用に関する上記のすべての回答に同意しますが、リストから追加/削除して、以下のように新しいリストを取得することもできます。

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

または

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

8

どうやら、デフォルトのKotlinのリストは不変です。変更可能なリストを作成するには、以下のようにMutableListを使用する必要があります

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

それでも更新されますが、本当に変更したいリストでない限り、MutableListを使用することはお勧めしません。読み取り専用コレクションがより優れたコーディングを提供する方法については、https: //hackernoon.com/read-only-collection-in-kotlin-leads-to-better-coding-40cdfa4c6359を参照してください


を使用することは正しいですがMutableList、で初期化してnullも機能しません。タイプのnull許容のレシーバーでは、安全またはnull以外のアサートされた呼び出しのみが許可されMutableList<Int>ます。
fulvio 2016年

それは私の側で動作し、エラーは見つかりませんでした。必要なとき以外に、初期化する必要はありませんdoSomething
Elye

@Elyeこれは古い答えと質問であることを知っていますがlateinit、リストをnull可能にする代わりに使用することがこの問題を回避する適切な方法です。lateinitKotlinの最初から追加されたかどうか覚えていないが、これは間違いなく今日使用するための解決策である:-)
Darwind

5

Kotlinでは、MutableListまたはを使用する必要がありArrayListます。

MutableList作業方法を見てみましょう:

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) 
}

ArrayList作業方法を見てみましょう:

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

このような新しいものを作成することで行うことができます。

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

これで、list2を使用できるようになりました。ありがとうございます。



2

可変性をビルダーに制限する

ここでの上位の回答は、読み取り専用List(注:読み取り専用であり、「不変」ではない)との間のKotlinの違いを正しく説明していますMutableList

一般に、読み取り専用リストを使用するように努めるべきですが、特に、機能しないインターフェースを備えたサードパーティのライブラリを扱う場合には、構築時に可変性が依然として役立つことがよくあります。そのような使用などの代替構造の技術が利用できるされていない場合、のためにlistOf直接、等の機能的構築物を適用foldまたはreduce、下記のような単純な「ビルダー機能」構築物はうまく一時的可変一方から読み取り専用リストを生成します。

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()

これは、再利用可能なインラインユーティリティ関数にうまくカプセル化できます。

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

これは次のように呼び出すことができます:

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

これで、すべての変更可能性が読み取り専用リストの作成に使用される1つのブロックスコープに分離され、残りのコードはビルダーから出力される読み取り専用リストを使用します。

更新:Kotlin 1.3.70以降、buildList上記の正確な関数は、その類似体およびとともに、実験関数として標準ライブラリで使用できます。参照してくださいhttps://blog.jetbrains.com/kotlin/2020/03/kotlin-1-3-70-released/をbuildSetbuildMap


適用方法も使用anotherList.ForEach {追加(FOO)} .appy内部{}内のビジネスロジックとうまくおかげ
BENN1TH

1

不変データの概念では、おそらくこれがより良い方法です。

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

1

AはlistあるimmutableことでDefault、使用することができ、ArrayList代わりに。このような :

 val orders = arrayListOf<String>()

次に、add/delete以下のようにこれからアイテムを作成できます。

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

デフォルトでArrayListは、mutableその上で操作を実行できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.