59

How can I use Stack (from java) in Kotlin?

Or theres any other alternative?

  • I'm trying to convert list to Stack
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
  • 22
    Don't use `Stack` anymore, it's very old java and relies on `Vector`. Instead use `Deque`, implemented by e.g. `ArrayDeque` or `LinkedList` – msrd0 Oct 24 '17 at 03:13
  • the stack implementation in java is quite bad either use the suggestion of @msrd0 or implement your own stack – tung Apr 16 '18 at 10:36

7 Answers7

52

Kotlin 1.3.70 introduced the kotlin.collections.ArrayDeque class, which functions as both a queue and a stack, like Java's java.util.Deque (Deque meaning "double-ended queue"). It was created out of a necessity for a multiplatform ArrayDeque implementation.

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)

Note that if an ArrayDeque is empty when you call removeFirst or removeLast, it will throw a kotlin.NoSuchElementException. If you don't want to check the size of your deque every time you need to access it, then you should use the removeFirstOrNull and removeLastOrNull functions.


Optional Snippets

ArrayDeque constructor function:

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

Stack-like ArrayDeque calls:

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

inline fun <T> ArrayDeque<T>.pop() = removeLastOrNull()          // returns T?
Maow
  • 661
  • 5
  • 8
43
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]
CFrei
  • 3,552
  • 1
  • 15
  • 29
sandeep549
  • 496
  • 4
  • 6
  • 2
    This should be mentioned more in this thread - don't use Stack, instead use Deque. For reasons why: https://stackoverflow.com/questions/12524826/why-should-i-use-deque-over-stack – Martyn Mar 23 '20 at 11:26
  • 1
    Be careful because the iteration order of `ArrayDeque` when used as a stack is wrong. – Nikola Mihajlović Dec 25 '20 at 22:25
25

You can use following:

/**
 * 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
Community
  • 1
  • 1
Malwinder Singh
  • 6,644
  • 14
  • 65
  • 103
16

This is done in the same way as you would in Java, but with Kotlin syntax - notably different are the val keyword and lack of new keyword. For example:

import java.util.Stack
...
val someList = ArrayList()
...
val stack = Stack()
stack.addAll(someList)
Ed Kohlwey
  • 468
  • 2
  • 8
12

This is a few years old but I suspect there's room for a different approach. If you want to use a stack structure in Kotlin you certainly don't need to resort to Java. You could easily just create a new class with an internal Kotlin list and stack-like public functions, or use Kotlin's extension methods to give an existing Kotlin collection "stack-like" functionality, for example:

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 

Then, optionally, you could use a typealias to make it more obvious what you're trying to do when using those functions:

typealias Stack = MutableList<MyClass>

Then create one and use it:

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

etc

adammtlx
  • 871
  • 7
  • 13
8

I don't believe there's a specific separate implementation of Stack in Kotlin. You could definitely use the answer by Ed.

Alternatively, you could use a mutableListOf<DataType> construct, and then have custom methods that are on top of this.

It would be something like this :

var stackDemo = mutableListOf<String>()

To push an element

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

To pop an element

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

You can refer to this Github link for a model implementation

Satej S
  • 2,113
  • 1
  • 16
  • 22
  • 1
    The use of 'count' here is unnecessary for adding elements, since it is the default location for single-parameter 'add'. Thus, 'stackDemo.add("One")' will suffice. Also, for removing elements, you should be using count()-1, not count(), or you will get exceptions thrown. – Some Guy Jan 24 '19 at 11:09
  • Is **mutableList** more memory-efficient than **stack**? – IgorGanapolsky Mar 12 '19 at 20:43
8

you can define Stack like it.

val stack = Stack<YourStackType>()

notice that set the data type of your stack, for example stack of Int is like this:

val stack = Stack<Int>()

after that you can use push , pop , or other stack operations

example for Int stack :

a:Int = 10
stack.push(a)
a = stack.pop()
Ali
  • 626
  • 1
  • 11
  • 29