Kotlin: java.lang.UnsupportedOperationException в элементе добавления MutableList

76
2

Я реализую алгоритм стека для цели исследования в Котлине

class Stack<T:Comparable<T>>(list:MutableList<T>) {

var items: MutableList<T> = list

fun isEmpty():Boolean = this.items.isEmpty()

fun count():Int = this.items.count()

fun push(element:T) {
val position = this.count()
this.items.add(position, element)
}

override fun toString() = this.items.toString()

fun pop():T? {
if (this.isEmpty()) {
return null
} else {
val item = this.items.count() - 1
return this.items.removeAt(item)
}
}

fun peek():T? {
if (isEmpty()) {
return null
} else {
return this.items[this.items.count() - 1]
}
}

}

И я пытаюсь выполнить с помощью этого кода:

fun main(args: Array<String>) {

var initialValue = listOf<Int>(10) as MutableList<Int>
var stack = Stack<Int>(initialValue)
stack.push(22)
println(stack.count())
println(stack.isEmpty())
println(stack.pop())
println(stack.count())
println(stack.isEmpty())

}

Когда я запускаю код, я получаю эту ошибку:

Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at Stack.push(Stack.kt:17)
at StackKt.main(Stack.kt:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

Это связано с последующей строкой, реализованной в методе push (element: T):

 this.items.add(position, element)

Самое странное, что я использовал очень похожий код, реализующий упорядоченный массив, и он отлично работает.

У вас есть представление о том, что я делаю неправильно?

спросил(а) 2021-01-25T14:07:41+03:00 4 месяца, 2 недели назад
1
Решение
116

listOf<Int> не является изменчивым. Согласно документу:

fun <T> listOf(vararg elements: T): List<T> (source) Возвращает новый список доступных для чтения элементов. Возвращенный список является сериализуемым (JVM).

mutableListOf<> этого вы должны использовать mutableListOf<>.

Причина, по которой as MutableList разрешена здесь, заключается в том, что listOf(10) возвращает Collections.singletonList(10) который возвращает java.util.List (который, по kotlin.collections.MutableList Kotlin, реализует интерфейс kotlin.collections.MutableList). Таким образом, компилятор не знает, что он не изменен до тех пор, пока не будет вызван метод mutating во время выполнения и выбрасывает исключение.

ответил(а) 2021-01-25T14:07:41+03:00 4 месяца, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема