【问题标题】:How can I use stack in Kotlin?如何在 Kotlin 中使用堆栈?
【发布时间】:2018-04-04 15:10:53
【问题描述】:

如何在 Kotlin 中使用 Stack(来自 java)?

或者还有其他选择吗?

  • 我正在尝试将列表转换为堆栈

【问题讨论】:

  • 不要再使用Stack,它是非常古老的java并且依赖于Vector。而是使用Deque,由例如实现。 ArrayDequeLinkedList
  • java中的堆栈实现很糟糕,要么使用@msrd0的建议,要么实现你自己的堆栈

标签: kotlin stack


【解决方案1】:

Kotlin 1.3.70 引入了kotlin.collections.ArrayDeque 类,该类既可用作队列,也可用作堆栈,就像 Java 的 java.util.Deque(Deque 意为“双端队列”)。它是出于多平台 ArrayDeque 实现的需要而创建的。

val stack = ArrayDeque(listOf(1, 2, 3)) // stack: [1, 2, 3]
stack.addLast(0)                        // stack: [1, 2, 3, 0]         (push)
val value = stack.removeLast()          // value: 0, stack: [1, 2, 3]  (pop)

请注意,如果在您调用removeFirstremoveLastArrayDeque 为空,则会抛出kotlin.NoSuchElementException。如果您不想在每次需要访问时检查双端队列的大小,那么您应该使用removeFirstOrNullremoveLastOrNull 函数。


可选片段

ArrayDeque构造函数:

inline fun <T> arrayDequeOf(vararg elements: T) = ArrayDeque(elements.toList())
// ...
val stack = arrayDequeOf(1, 2, 3)

Stack-like ArrayDeque 调用:

inline fun <T> ArrayDeque<T>.push(element: T) = addLast(element) // returns Unit

inline fun <T> ArrayDeque<T>.pop() = removeLastOrNull()          // returns T?

【讨论】:

    【解决方案2】:

    您可以使用以下内容:

    /**
     * Stack as type alias of Mutable List
     */
    typealias Stack<T> = MutableList<T>
    
    /**
     * Pushes item to [Stack]
     * @param item Item to be pushed
     */
    inline fun <T> Stack<T>.push(item: T) = add(item)
    
    /**
     * Pops (removes and return) last item from [Stack]
     * @return item Last item if [Stack] is not empty, null otherwise
     */
    fun <T> Stack<T>.pop(): T? = if (isNotEmpty()) removeAt(lastIndex) else null
    
    /**
     * Peeks (return) last item from [Stack]
     * @return item Last item if [Stack] is not empty, null otherwise
     */
    fun <T> Stack<T>.peek(): T? = if (isNotEmpty()) this[lastIndex] else null
    

    【讨论】:

    • 您将如何初始化或构造这样的堆栈? val stack:Stack&lt;Char&gt; = MutableList(0){'.'}val stack = MutableList(0){' '} as Stack&lt;Char&gt;?
    【解决方案3】:
    import java.util.ArrayDeque
    
    var stack = ArrayDeque<Int>()
    stack.push(1)
    stack.push(2)
    stack.push(3)
    stack.push(4)
    println(stack)           // --> [4, 3, 2, 1]
    println(stack.isEmpty()) // --> false
    
    println(stack.peek())    // --> 4
    println(stack)           // --> [4, 3, 2, 1]
    
    println(stack.pop())     // --> 4
    println(stack)           // --> [3, 2, 1]
    
    stack.push(9)
    println(stack)           // --> [9, 3, 2, 1]
    

    【讨论】:

    • 这应该在这个线程中更多地提到 - 不要使用 Stack,而是使用 Deque。原因:stackoverflow.com/questions/12524826/…
    • 注意ArrayDeque作为栈使用时的迭代顺序是错误的。
    【解决方案4】:

    这已经有几年历史了,但我怀疑还有采用不同方法的空间。如果你想在 Kotlin 中使用堆栈结构,你当然不需要求助于 Java。您可以轻松地创建一个带有内部 Kotlin 列表和类似堆栈的公共函数的新类,或者使用 Kotlin 的扩展方法为现有的 Kotlin 集合提供“类似堆栈”的功能,例如:

    fun <T> MutableList<T>.push(item: T) = this.add(this.count(), item)
    fun <T> MutableList<T>.pop(): T? = if(this.count() > 0) this.removeAt(this.count() - 1) else null
    fun <T> MutableList<T>.peek(): T? = if(this.count() > 0) this[this.count() - 1] else null
    fun <T> MutableList<T>.hasMore() = this.count() > 0 
    

    然后,您可以选择使用 typealias 来使您在使用这些函数时尝试做的事情更加明显:

    typealias Stack = MutableList<MyClass>
    

    然后创建一个并使用它:

    val myStack: Stack = mutableListOf()
    myStack.push(MyClass())
    myStack.pop()
    

    【讨论】:

      【解决方案5】:

      你可以像这样定义 Stack。

      val stack = Stack<YourStackType>()
      

      注意设置堆栈的数据类型,例如Int的堆栈是这样的:

      val stack = Stack<Int>()
      

      之后你可以使用 push 、 pop 或其他堆栈操作

      Int 堆栈示例:

      a:Int = 10
      stack.push(a)
      a = stack.pop()
      

      【讨论】:

        【解决方案6】:

        我认为 Kotlin 中没有特定的 Stack 单独实现。您绝对可以使用 Ed 的答案。

        或者,您可以使用mutableListOf&lt;DataType&gt; 构造,然后在此之上使用自定义方法。

        应该是这样的:

        var stackDemo = mutableListOf<String>()
        

        推送一个元素

        var count = stackDemo.count()
        stackDemo.add(count,"One")
        

        弹出一个元素

        var count = stackDemo.count()
        stackDemo.removeAt(count)
        

        模型实现可以参考这个Github link

        【讨论】:

        • 这里不需要使用'count'来添加元素,因为它是单参数'add'的默认位置。因此,'stackDemo.add("One")' 就足够了。此外,对于删除元素,您应该使用 count()-1,而不是 count(),否则会抛出异常。
        • mutableList 是否比 stack 更节省内存?
        【解决方案7】:

        这与在 Java 中的方式相同,但使用 Kotlin 语法 - 显着不同的是 val 关键字和缺少 new 关键字。例如:

        import java.util.Stack
        ...
        val someList = ArrayList()
        ...
        val stack = Stack()
        stack.addAll(someList)
        

        【讨论】:

        猜你喜欢
        • 2020-05-29
        • 2021-12-25
        • 2015-03-17
        • 1970-01-01
        • 1970-01-01
        • 2022-01-22
        • 2018-12-02
        • 2016-03-05
        • 1970-01-01
        相关资源
        最近更新 更多