Kotlin:MutableList中的java.lang.UnsupportedOperationException添加元素

时间:2016-04-05 01:19:02

标签: java algorithm stack kotlin

我正在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,它运行得很好。

你知道我做错了什么吗?

2 个答案:

答案 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 (10).toMutableList()

下面是一个有效的示例:

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