我正在Kotlin中实现用于研究目的的堆栈算法
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)
最奇怪的是我使用了一个非常相似的代码来实现orderedArray,它运行得很好。
你知道我做错了什么吗?
答案 0 :(得分:7)
listOf<Int>
并非真正可变。根据{{3}}:
fun <T> listOf(vararg elements: T): List<T> (source)
返回给定元素的新只读列表。返回的列表是 可序列化(JVM)。
您应该使用the doc代替。
此处允许as MutableList
的原因是listOf(10)
返回Collections.singletonList(10)
,返回java.util.List
(Kotlin假定实现kotlin.collections.MutableList
接口)。因此,在运行时调用mutating方法并抛出异常之前,编译器并不知道它是不可变的。
答案 1 :(得分:3)
您可以通过调用toMutableList()API来解决此问题,而不是使用智能强制转换(as)。
尝试:var initialValue = listOf
下面是一个有效的示例:
fun main(){
val x : List<String> = listOf("foo", "bar", "baz")
//val y: MutableList<String> = x as MutableList<String> throws UnsupportedOperationException
val y: MutableList<String> = x.toMutableList()
y.add("sha")
println(y) // [foo, bar, baz, sha]
}