Kotlin List отсутствуют "добавить", "удалить" и т.д.?
В 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 кастинг не требуется. И это побеждает цель иметь абстрактный список классов
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
(myList!! as ArrayList).add(10)
(myList!! as ArrayList).remove(10)
}
}
Есть ли способ использовать List, но не нужно его бросать, например, что можно сделать на Java?
Ответы
Ответ 1
В отличие от многих языков, Котлин различает изменчивые и неизменные коллекции (списки, наборы, карты и т.д.). Точный контроль над тем, когда коллекции можно редактировать, полезно для устранения ошибок и для разработки хороших 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()
также должен работать.
Ответ 2
Определение коллекции списков в 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
Ошибка: Котлин: Назначение операторов неоднозначность:
открытый оператор fun Collection.plus(element: String): список определен в kotlin.collections
@InlineOnly общедоступный встроенный оператор fun MutableCollection.plusAssign(element: String): модуль, определенный в kotlin.collections
см. также: https://kotlinlang.org/docs/reference/collections.html
Ответ 3
По-видимому, список 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 о том, как коллекция только для чтения обеспечивает лучшее кодирование.
Ответ 4
Согласитесь со всеми приведенными выше ответами об использовании MutableList, но вы также можете добавить/удалить из списка и получить новый список, как показано ниже.
val newListWithElement = existingList + listOf(element)
val newListMinusElement = existingList - listOf(element)
Или же
val newListWithElement = existingList.plus(element)
val newListMinusElement = existingList.minus(element)
Ответ 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)
}
Надеюсь это поможет.
Ответ 6
https://kotlinlang.org/docs/reference/collections.html
В соответствии с приведенной выше ссылкой List <E> неизменен в Котлине.
Однако это сработает:
var list2 = ArrayList<String>()
list2.removeAt(1)
Ответ 7
В концепции неизменяемых данных, может быть, это лучший способ:
class TempClass {
val list: List<Int> by lazy {
listOf<Int>()
}
fun doSomething() {
list += 10
list -= 10
}
}
Ответ 8
Default
list
immutable
, вместо него можно использовать ArrayList
. как это:
val orders = arrayListOf<String>()
затем вы можете add/delete
элементы из этого, как показано ниже:
orders.add("Item 1")
orders.add("Item 2")
по умолчанию ArrayList
является mutable
поэтому вы можете выполнять над ним операции.
Ответ 9
Верхние ответы здесь правильно говорят о разнице в 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")
}
Теперь вся изменчивость изолирована от одной области блока, используемой для построения списка только для чтения, а остальная часть вашего кода использует список только для чтения, который выводится из компоновщика.
Ответ 10
Вы можете сделать с созданием нового, как это.
var list1 = ArrayList<Int>()
var list2 = list1.toMutableList()
list2.add(item)
Теперь вы можете использовать list2, спасибо.