Kotlin의 목록에“add”,“remove”, 누락 된“put”등이 없습니까?


197

자바에서 우리는 다음을 할 수 있습니다

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다음 나중에 전화없이 add !!. 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
목록을 즉시 초기화하는 경우 목록을 nullable로 만들 필요가 없습니다. 나는 당신의 대답을 편집했습니다.
Kirill Rakhman

37

다른 방법으로 Kotlin에서 List 컬렉션 정의 :

  • 불변 (읽기 전용) 목록이있는 불변 변수 :

    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 : 할당 연산자 모호성 :
        public operator fun Collection.plus (element : String) : kotlin.collections에 정의 된 목록
        @InlineOnly public 인라인 연산자 fun MutableCollection.plusAssign (element : String) : kotlin.collections에 정의 된 단위


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


9

MutableList 사용에 대한 위의 모든 답변에 동의하지만 List에서 추가 / 제거하고 아래처럼 새 목록을 얻을 수도 있습니다.

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작동하지 않습니다. 안전하거나 널이 아닌 주장 호출 만 유형의 널 입력 가능 수신자에서 허용됩니다 MutableList<Int>.
fulvio 2016 년

내 끝에서 작동하며 오류가 없습니다. 언제 필요할 때가 아니면 초기화하지 않아도됩니다doSomething
Elye

@Elye 나는 이것이 오래된 대답과 질문이라는 것을 알고 있지만 lateinit목록을 nullable로 만드는 대신 사용하는 것이이 문제에 대한 올바른 방법입니다. lateinit그래도 Kotlin의 시작 부분에서 추가 되었는지 기억하지 못하지만 이것은 오늘날 그것을 사용하는 솔루션입니다 :-)
Darwind

5

코 틀린에서는 사용할 필요 MutableListArrayList.

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

빌더에 대한 돌연변이 제한

여기에 가장 많이 나오는 대답은 Kotlin의 읽기 전용 List(참고 : "불변"이 아닌 읽기 전용 )과 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")
}

이제 모든 가변성은 읽기 전용 목록을 구성하는 데 사용되는 하나의 블록 범위로 분리되며 나머지 코드는 빌더에서 출력되는 읽기 전용 목록을 사용합니다.

UPDATE : 코 틀린 1.3.70 현재, 정확한 buildList위의 기능은 사용할 수 의 유사 물질과 함께 실험적인 기능과 표준 라이브러리 buildSetbuildMap. https://blog.jetbrains.com/kotlin/2020/03/kotlin-1-3-70-released/를 참조 하십시오 .


고마워하고 apply 메소드 내에서 비즈니스 로직과 잘 작동했으며, 심지어 .appy {} 내부에 anotherList.ForEach {add (foo)}를 사용했습니다.
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.