How can I use stack in Kotlin? - kotlin

How can I use Stack (from java) in Kotlin?
Or theres any other alternative?
I'm trying to convert list to Stack

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?

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]

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

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)

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

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()

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

Related

What is the function of the * operation in Kotlin?

The Code A is from the offical sample project.
I don't understand what val tasks = remember { mutableStateListOf(*allTasks) } mean, could you tell me ?
BTW, Android Studio give me some information, you can see Image A
Code A
#Composable
fun Home() {
// String resources.
val allTasks = stringArrayResource(R.array.tasks)
val allTopics = stringArrayResource(R.array.topics).toList()
// The currently selected tab.
var tabPage by remember { mutableStateOf(TabPage.Home) }
// True if the whether data is currently loading.
var weatherLoading by remember { mutableStateOf(false) }
// Holds all the tasks currently shown on the task list.
val tasks = remember { mutableStateListOf(*allTasks) }
...
}
Image A
From the documentation of varargs:
When you call a vararg -function, you can pass arguments individually, for example asList(1, 2, 3). If you already have an array and want to pass its contents to the function, use the spread operator (prefix the array with *):
val a = arrayOf(1, 2, 3)
val list = asList(-1, 0, *a, 4)
As you see, it expands an array to multiple values for use in a vararg. If you havd an array containing the elements 1, 2, 3, you can pass *yourArray to a method that is equivalent to yourMethod(1,2,3).
In Kotlin * is the Spread Operator.
From docs :
When you call a vararg -function, you can pass arguments individually, for example asList(1, 2, 3). If you already have an array and want to pass its contents to the function, use the spread operator (prefix the array with *):
val a = arrayOf(1, 2, 3)
val list = asList(-1, 0, *a, 4)
In this case tasks will contain the list of strings from R.array.tasks

Initializing a list in kotlin

I am trying to initlaise a list as part of a constructor argument. But I do not understand what it wants from me
distortion = List(
size = 10,
init = 0
)
The list is of type room entity
var distortion: List<DistortionCacheEntity>? = null
The init part is underlined in red. I dont know what to put in there or how to write it. Could someone help.
The function you are trying to invoke looks like this:
public inline fun <T> List(size: Int, init: (index: Int) -> T): List<T>
So init here is not an Integer but rather a function. Invoke like so:
distortion = List(size = 10) { index : Int ->
//Create object that the list needs to hold
}
var distortion: List<DistortionCacheEntity>? = null
distortion = List(10) { index -> DistortionCacheEntity()}
The simplest way to initialize a list is with kotlin library function listOf(...)
For example,
listOf(1, 2, 3) // [1, 2, 3]

why i cant merge two list in kotlin [duplicate]

This question already has answers here:
Kotlin Error: Unresolved reference: merge (for list.merge())
(2 answers)
Closed 3 years ago.
i'm reading anotonio leava book about kotlin
there is a function named "merge" it can merge two list with each other
this is a code that author write in his book:
val list = listOf(1,2,3,4,5,6)
val anotherlist = listOf(7,8,9,10,11,12)
assertEquals(listOf(8,10,12,14,16,18),list.merge(anotherlist){it1,it2 - > it1+it2})
it means merge is plusing two list
but when i write code myself
my idea intelij doesnt know the func name
and it doesnt work
can you help me
sorry because of my english
You can do it with the use of map
val x: List<Int> = listOf(1,2,3,4,5,6)
val y: List<Int> = listOf(2,3,4,5,6,7)
val sums = (x.indices).map { x[it] + y[it] }
output
[3, 5, 7, 9, 11, 13]
instead of map you can use zip function
fun main(args: Array<String>) {
val list1 = listOf(4, 5, 6)
val list2 = listOf(1, 2, 3)
val result = list1.zip(list2) { e1, e2 -> e1 + e2 }
println(result) // prints [5, 7, 9]
}
merge is neither a member function of List, nor does the kotlin standard library provide an extension function. But you can define one by your own (and I suspect, that's what the author did)
fun <E> List<E>.merge(anotherlist: List<E>, operation: (E, E) -> E): List<E> {
// you probably want to check cardinalities of the two lists
return indices.map { operation(this[it], anotherlist[it]) }
}

Custom 'typesafe' Int Types

What I would like to have is two different integer types which are semantically distinguishable.
E.g. in this code a 'Meter' type and a 'Pixel' int type
typealias Meter = Int
typealias Pixel = Int
fun Meter.toPixel() = this * 100
fun Pixel.toMeter() = this / 100
fun calcSquareMeters(width: Meter, height: Meter) = width * height
fun calcSquarePixels(width: Pixel, height: Pixel) = width * height
fun main(args: Array<String>) {
val pixelWidth: Pixel = 50
val pixelHeight: Pixel = 50
val meterWidth: Meter = 50
val meterHeight: Meter = 50
calcSquareMeters(pixelWidth, pixelHeight) // (a) this should not work
pixelWidth.toPixel() // (b) this should not work
}
The problem with this solution is
(a) that I can call calcSquareMeters with my 'Pixel' type which I don't want to be possible and
(b) that I can call the toPixel() extension function which I only want to have for my 'Meter' type on my 'Pixel' type which I don't want to be possible.
I guess this is the intended behaviour of typealias, so I guess to achieve my goal I have to use something different than typealias...
So how can I achieve this?
In addition to the existing answer: If you have a lot of common functionality between the two types and don't want to duplicate it, you can work with an interface:
interface MetricType<T> {
val value: Int
fun new(value: Int): T
}
data class Meter(override val value: Int) : MetricType<Meter> {
override fun new(value: Int) = Meter(value)
}
data class Pixel(override val value: Int) : MetricType<Pixel> {
override fun new(value: Int) = Pixel(value)
}
Like this, you can easily define operations on the base interface, such as addition, subtraction and scaling:
operator fun <T : MetricType<T>> T.plus(rhs: T) = new(this.value + rhs.value)
operator fun <T : MetricType<T>> T.minus(rhs: T) = new(this.value + rhs.value)
operator fun <T : MetricType<T>> T.times(rhs: Int) = new(this.value * rhs)
The combination of interface and generics ensures type safety, so you do not accidentally mix types:
fun test() {
val m = Meter(3)
val p = Pixel(7)
val mm = m + m // OK
val pp = p + p // OK
val mp = m + p // does not compile
}
Keep in mind that this solution comes at a runtime cost due to the virtual functions (compared to rewriting the operators for each type separately). This in addition to the overhead of object creation.
Indeed, typealiases don't guarantee this sort of type safety. You'll have to create wrapper classes around an Int value instead to achieve this - it's a good idea to make these data classes so that equality comparisons work on them:
data class Meter(val value: Int)
data class Pixel(val value: Int)
Creation of instances of these classes can be solved with extension properties:
val Int.px
get() = Pixel(this)
val pixelWidth: Pixel = 50.px
The only problematic thing is that you can no longer directly perform arithmetic operations on Pixel and Meter instances, for example, the conversion functions would now look like this:
fun Meter.toPixel() = this.value * 100
Or the square calculations like this:
fun calcSquareMeters(width: Meter, height: Meter) = width.value * height.value
If you really need direct operator use, you can still define those, but it will be quite tedious:
class Meter(val value: Int) {
operator fun times(that: Meter) = this.value * that.value
}
fun calcSquareMeters(width: Meter, height: Meter) = width * height
There is a proposal (not yet guaranteed to be accepted) to add inline classes for this purpose. I.e.
#InlineOnly inline class Meter(val value: Int)
will really be an Int at runtime.
See https://github.com/zarechenskiy/KEEP/blob/28f7fdbe9ca22db5cfc0faeb8c2647949c9fd61b/proposals/inline-classes.md and https://github.com/Kotlin/KEEP/issues/104.
From kotlin doc:
Type aliases do not introduce new types. They are equivalent to the corresponding underlying types. When you add typealias Predicate and use Predicate in your code, the Kotlin compiler always expand it to (Int) -> Boolean. Thus you can pass a variable of your type whenever a general function type is required and vice versa
This means that there isn't possible check over your typealias, and you are rally declaring your extensions functions as:
fun Int.toPixel() = this * 100
fun Int.toMeter() = this / 100
fun calcSquareMeters(width: Int, height: Int) = width * height
fun calcSquarePixels(width: Int, height: Int) = width * height
I fear the only way to achieve that you want is implementing an extra class for each type.
I would also go with the solution from TheOperator. But I would like to add the inline keyword to the operator functions. By doing so you could avoid a virtual function call when ever you use this operators.
inline operator fun <T : MetricType<T>> T.plus(rhs: T) = new(this.value + rhs.value)
inline operator fun <T : MetricType<T>> T.minus(rhs: T) = new(this.value + rhs.value)
inline operator fun <T : MetricType<T>> T.times(rhs: Int) = new(this.value * rhs)

Kotlin iterator to list?

I have an iterator of strings from fieldNames of JsonNode:
val mm = ... //JsonNode
val xs = mm.fieldNames()
I want to loop over the fields while keeping count, something like:
when mm.size() {
1 -> myFunction1(xs[0])
2 -> myFunction2(xs[0], xs[1])
3 -> myFunction3(xs[0], xs[1], xs[2])
else -> print("invalid")
}
Obviously the above code does not work as xs the Iterator cannot be indexed like so. I tried to see if I can convert the iterator to list by mm.toList() but that does not exist.
How can I achieve this?
Probably the easiest way is to convert iterator to Sequence first and then to List:
listOf(1,2,3).iterator().asSequence().toList()
result:
[1, 2, 3]
I would skip the conversion to sequence, because it is only a few lines of code.
fun <T> Iterator<T>.toList(): List<T> =
ArrayList<T>().apply {
while (hasNext())
this += next()
}
Update:
Please keep in mind though, that appending to an ArrayList is not that performant, so for longer lists, you are better off with the following, or with the accepted answer:
fun <T> Iterator<T>.toList(): List<T> =
LinkedList<T>().apply {
while (hasNext())
this += next()
}.toMutableList()
You can turn an Iterator into an Iterable using Iterable { iterator } on which you can then call toList():
Iterable { listOf(1,2,3).iterator() }.toList() // [1, 2, 3]