How to use comparator in priority queue kotlin - kotlin

Hey I want to use custom comparator in priority queue in kotlin. I have data class
Product.kt
data class Product(val value: String? = null, val price: String? = null) {
var priceInLong = price?.toLong()
}
I want to create a min heap where price value will be minimum. I am creating the object but it giving me some kind of error
fun main() {
var queue = PriorityQueue<Long> { p1: Product, p2: Product ->
p1.priceInLong?.let {
p2.priceInLong?.minus(it)
}
}
val list = listOf(
Product("1", "4.83"),
Product("2", "4.53"),
Product("3", "3.54"),
Product("4", "3.66"),
Product("5", "5.16")
)
}
error
None of the following functions can be called with the arguments supplied.
<init>((MutableCollection<out TypeVariable(E)!>..Collection<TypeVariable(E)!>?))   where E = TypeVariable(E) for   constructor PriorityQueue<E : Any!>(c: (MutableCollection<out E!>..Collection<E!>?)) defined in java.util.PriorityQueue
<init>(Comparator<in TypeVariable(E)!>!)   where E = TypeVariable(E) for   constructor PriorityQueue<E : Any!>(comparator: Comparator<in E!>!) defined in java.util.PriorityQueue
<init>(PriorityQueue<out TypeVariable(E)!>!)   where E = TypeVariable(E) for   constructor PriorityQueue<E : Any!>(c: PriorityQueue<out E!>!) defined in java.util.PriorityQueue
<init>(SortedSet<out TypeVariable(E)!>!)   where E = TypeVariable(E) for   constructor PriorityQueue<E : Any!>(c: SortedSet<out E!>!) defined in java.util.PriorityQueue
<init>(Int)   where E = TypeVariable(E) for   constructor PriorityQueue<E : Any!>(initialCapacity: Int) defined in java.util.PriorityQueue
image
1. I want to solve this error and add value by price which is minimum comes first.
2. Is my above queue comparator logic is correct to use min heap?
Thankss
UPDATE
I tried this suggestion
var queue = PriorityQueue<Product> { p1, p2 ->
return if (p1.priceInLong != null && p2.priceInLong != null) {
p2.priceInLong - p1.priceInLong
} else {
0
}
}
getting error
UPDATE 2
val queue = PriorityQueue<Product> { p1, p2 ->
val priceOne = p1.priceInLong
val priceTwo = p2.priceInLong
if (priceOne != null && priceTwo != null) {
if(priceOne == priceTwo){
return 0
}
} else {
return 0
}
}
data class Product(val value: String? = null, val price: String? = null) {
val priceInLong = price?.toLong()
}

This:
{ p1: Product, p2: Product ->
p1.priceInLong?.let {
p2.priceInLong?.minus(it)
}
}
returns null if p1.priceInLong is null (the let block isn't executed), or if p2.priceInLong is null (the let block returns null). That's what the null-safety checking with ? does.
You're getting the error because your Comparator function needs to return an Int, but yours returns Int?, i.e. a nullable int value - could be an int, could be null. So it doesn't match the required constructor, that's why it's complaining that none of the functions match.
So you need to decide what to do if one (or both) of those values are null, and return an integer instead of any nulls, so your function returns Int and not Int?
If what you're saying in the comments is correct, and neither of those values will ever be null, you can just assert that with !!
{ p1: Product, p2: Product ->
p2.priceInLong!! - p1.priceInLong!!
}
But using !! is a bad sign - how do you know they'll never be null? If you can say that for sure, why is priceInLong nullable in the first place?

I want to solve this error
Two problems here:
Type argument of PriorityQueue should be a Product (if you want to store these objects in it).
Lambda of Comparator should return Int, not Long?. If it's guaranteed, that there will be no Products with priceInLong == null, you may just use the not-null assertion operator to get rid of nullability and then get sign of difference to avoid possible integer overflow of .toInt() conversion:
val queue = PriorityQueue<Product> { p1, p2 -> (p1.priceInLong!! - p2.priceInLong!!).sign }

Related

Type mismatch error when adding a map value to a variable (Kotlin)

I want to add a value from a MutableMap to the total, but I keep getting Type mismatch: inferred type is Int? but Int was expected error and I don't know how to fix this issue
I tried calling the value as Int menu[item].toInt() and setting logic in the if statement that checks that the item is indeed Int, but nothing helped.
Please, see the code below
fun main() {
val order = Order()
order.placeOrder("Noodles")
}
val menu: MutableMap<String, Int> = mutableMapOf("Noodles" to 10,
"Vegetables Chef's Choice" to 5,
)
class Order {
var total = 0
fun placeOrder(vararg orderedItems: String) {
for (item in orderedItems) {
if (item in menu) {
total += menu[item]
}
}
}
}
Your call to menu[item] is a shorthand for menu.get(item) which is defined as Map<K, out V>.get(key: K): V?.
In case no element with the specified key is found in the map, null is returned.
You may fix this by providing a default value, in case the returned value is null, e.g.:
total += menu[item] ?: 0
Map<K, out V> also provides alternatives, which provide Int instead of Int?.
You may use getValue(key: K): V, which throws an NoSuchElementException, when there is no element with the given key.
Alternatively, you can utilize getOrElse(key: K, defaultValue: () -> V): V or getOrDefault(key: K, defaultValue: V): V which both provide a fallback value instead of null.
Examples for the different alternatives below:
total += menu.getValue(item)
total += menu.getOrElse(item) { 0 }
total += menu.getOrDefault(item, 0)

How to find last node that satisfies where predicate in singly linked list?

write a method "lastWhere" that accepts a function called "where" of type (T) -> Boolean. The method returns the last element of type T to which the "where" function applies. If no matching element is found, null is returned.
call the method "lastwhere" on the linked list below. Find the last game that is more than 10 euros.
So far I've got this Code going for me.
I assume the only important piece of Code I need to edit is the "fun lastWhere" for task number 1)
the second task wants me to implement a way on the main function to find the last Game that is cheaper than 10 Euros.
class LinkedList<T> {
data class Node<T>(val data: T, var next: Node<T>?)
private var first: Node<T>? = null
override fun toString(): String = first?.toString() ?: "-"
fun isEmpty() = first == null
fun addLast(data: T) {
if (first == null) {
first = Node(data, first)
return
}
var runPointer = first
while (runPointer?.next != null) {
runPointer = runPointer.next
}
runPointer?.next = Node(data, null)
}
fun lastWhere (where: (T) -> Boolean): T? { // "where" function needs to be implemented
if (isEmpty()) return null
else {
var runPointer = first
while (runPointer?.next != null ) {
runPointer = runPointer.next
}
return runPointer?.data
}
}
}
data class Game(val title: String, val price: Double)
fun main() {
val list = LinkedList<Game>()
list.addLast(Game("Minecraft", 9.99))
list.addLast(Game("Overwatch", 29.99))
list.addLast(Game("Mario Kart", 59.99))
list.addLast(Game("World of Warcraft", 19.99))
var test = list.lastWhere ({it.price >= 10.00}) // This is probably wrong too, since I haven't got task 1) working
println (test)
}
Would appreciate any help!
Since you only store a reference to first node, you don't have any choice but to start at first and iterate. you will also have to keep a reference to last item that satisfied the where predicate, and keep updating this reference with every iteration.
fun lastWhere (where: (T) -> Boolean): T? {
var runPointer = first
var item: T? = null // init item to null, if nothing is found we return null
while (runPointer != null ) {
// For every node, execute the where function and if it returns true
// then update the return value
if(where(runPointer.data)) { item = runPointer.data }
runPointer = runPointer.next
}
return item
}

How to avoid nest 「null check」by "?.let"?

let in kotlin help me avoid some if(null?) doSomething.
But I have a problem.
A is the field of the object, And B is the field of Object A. they can be nullbale.
They in code like this.
class Obj {
var a : A?
}
class A {
var b : B?
}
I knew I can do it by double let:
A?.let {
it.B.let {
// a must nonnull
}
}
A?.B?.let {
// how to use A ,without null check again?
}
There are extension functions out there to achieve what you're looking for, you can find them in this thread https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946
But honestly, you're probably better of just using a basic if check here, if the variable is mutable you can assign it to a val first.
val _a = a
val _b = b
if (_a != null && _b != null) {
}
Edit: If you still really want to use let though, for this case you could create a pair and use takeIf
(a to b)
.takeIf { (a, b) ->
a != null && b != null
}
?.let { (a, b) ->
}
However the compiler won't smartcast the values as non-null, so you will still have to perform a non-null (!!) assertion on them.
You could implement it like a Swift guard with an elvis operator ?:
fun doSomething() {
val a = A ?: return
val b = B ?: return
doSomethingWith(a, b)
}
Here a and b are non-nullable references to the data you hold in In this case you'd just return from your function.
By default Kotlin avoids null values and for Null Safety it provides:
1) Safe Call Operator( ?. )
2) Not-Null Assertion( !! )
3) Elvis Opeartor( ?: )
4) Safe Call with let ( ?.let{...} )
Safe Call Operator( ?. ):Checks if the property is not null before performing any operations.
Not-Null Assertion( !! ) : Explicitly tells the compiler that the property is not null and if it’s null, please throw a null pointer exception (NPE)
Elvis Opeartor( ?: ): It's like ternary operator in java. If property is not null then left expression is returned otherwise right.
Safe Call with let ( ?.let{...} ): It will execute the let block only if property is not null
Example with Not Null Value inside property:
fun main() {
val name: String? = "Sumit"
println("Safe Call operator: ${name?.length}")
name?.let {
println("Safe Call wih let operator: ${name.length}")
}
val length = name?.length ?: 0
println("Elvis operator : $length")
println("Not Null Assertion Operator : ${name!!.length}")
}
Output (With Not Null Value inside property)
Safe Call operator: 5
Safe Call wih let operator: 5
Elvis operator : 5
Not Null Assertion Operator : 5
Output (With Null Value inside property)(val name: String? = null)
Safe Call operator: null
Elvis operator : 0
Exception in thread "main" kotlin.KotlinNullPointerException
at HelloKt.main(Hello.kt:14)
at HelloKt.main(Hello.kt)
Here, safe call with let is not executed!! And Not-Null assertion operator throws null pointer exception.
Your problem can use not-null assertion operator:
A?.B?.let {
// If A and B are not null then only this block will be executed.
A.someMethod()
B.someMethod()
}
You can use when as an or statement for multiple variables
when(null) {
a, b -> return //for your case of nested properties try something like "obj.a, obj?.a?.b"
else -> doSomethingWhenAAndBAreNotNull()
}
//or do something when a and b are not null here so you don't need to nest
Another option could be to write something like this
fun <A, B> A?.and(that: B?, block: (A, B) -> Unit) {
this?.let { a -> that?.let { b -> block(a, b) } }
}
and then use it like this
var first: Int?
var second: Int?
first.and(second) { f, s -> someFunction(f,s) }

Test closure of an extension function in Kotlin

Suppose we have the following code:
#ExperimentalCoroutinesApi
fun ProducerScope<DownloadableDataDto<out User>>.findInteresting(input: ReceiveChannel<DownloadableDataDto<out User>>,
communitiesCount: Int,
userCountMap: MutableMap<User, Int> = ConcurrentHashMap()) = createProducer(input) {
if (userCountMap.compute(it.data!!) { _, value ->
if (value == null) 1 else value + 1
} == communitiesCount) send(it)
}
This code checks if a user is a part of all of the communitiesCount communities. But this logic is enclosed inside a createChannel() higher order function, which I would not want to test at the moment. Is there a way to test only the internals? I assume I could probably extract that to a separate function as well, right?
And if I do it that way, let's say we have this instead:
#ExperimentalCoroutinesApi
fun ProducerScope<DownloadableDataDto<out User>>.findInteresting(input: ReceiveChannel<DownloadableDataDto<out User>>,
communitiesCount: Int,
userCountMap: MutableMap<User, Int> = ConcurrentHashMap()) = createProducer(input) {
sendIfInteresting(it, communitiesCount, userCountMap)
}
#ExperimentalCoroutinesApi
private suspend fun ProducerScope<DownloadableDataDto<out User>>.sendIfInteresting(userDto: DownloadableDataDto<out User>,
communitiesCount: Int,
userCountMap: MutableMap<User, Int>) {
if (userCountMap.compute(userDto.data!!) { _, value ->
if (value == null) 1 else value + 1
} == communitiesCount) send(userDto)
}
How would I mock the send(userDto) call? I can mock the ProducerScope object, but how would I call the real sendIfInteresting() method?

Swift 'if let' statement equivalent in Kotlin

In Kotlin is there an equivalent to the Swift code below?
if let a = b.val {
} else {
}
You can use the let-function like this:
val a = b?.let {
// If b is not null.
} ?: run {
// If b is null.
}
Note that you need to call the run function only if you need a block of code. You can remove the run-block if you only have a oneliner after the elvis-operator (?:).
Be aware that the run block will be evaluated either if b is null, or if the let-block evaluates to null.
Because of this, you usually want just an if expression.
val a = if (b == null) {
// ...
} else {
// ...
}
In this case, the else-block will only be evaluated if b is not null.
Let's first ensure we understand the semantics of the provided Swift idiom:
if let a = <expr> {
// then-block
}
else {
// else-block
}
It means this: "if the <expr> results in a non-nil optional, enter the then-block with the symbol a bound to the unwrapped value. Otherwise enter the else block.
Especially note that a is bound only within the then-block. In Kotlin you can easily get this by calling
<expr>?.also { a ->
// then-block
}
and you can add an else-block like this:
<expr>?.also { a ->
// then-block
} ?: run {
// else-block
}
This results in the same semantics as the Swift idiom.
My answer is totally a copy cat from the others. However, I cannot understand their expression easily. So I guess it would be nice to provide an more understandable answer.
In swift:
if let a = b.val {
//use "a" as unwrapped
}
else {
}
In Kotlin:
b.val?.let{a ->
//use "a" as unwrapped
} ?: run{
//else case
}
if let statement
Swift if let Optional Binding (so called if-let statement) is used to extract a non-optional value if one exists, or to do nothing if a value is nil.
Swift's if-let statement:
let b: Int? = 50
if let a: Int = b {
print("Good news!")
} else {
print("Equal to 'nil' or not set")
}
/* RESULT: Good news! */
In Kotlin, like in Swift, to avoid crashes caused by trying to access a null value when it’s not expected, a specific syntax (like b.let { } in second example) is provided for properly unwrapping nullable types:
Kotlin's equivalent1 of Swift's if-let statement:
val b: Int? = null
val a = b
if (a != null) {
println("Good news!")
} else {
println("Equal to 'null' or not set")
}
/* RESULT: Equal to 'null' or not set */
Kotlin’s let method, when used in combination with the safe-call operator ?:, provides a concise way to handle nullable expressions.
Kotlin's inline let function and Elvis Operator of Swift's nil coalescing operator:
val b: Int? = null
val a = b.let { nonNullable -> nonNullable } ?: "Equal to 'null' or not set"
println(a)
/* RESULT: Equal to 'null' or not set */
guard let statement
guard-let statement in Swift is simple and powerful. It checks for some condition and if it evaluates to be false, then the else statement executes which normally will exit a method.
Let's explore a Swift's guard-let statement:
let b: Int? = nil
func method() {
guard let a: Int = b else {
print("Equal to 'nil' or not set")
return
}
print("Good news!")
}
method()
/* RESULT: Equal to 'nil' or not set */
Kotlin's similar effect of Swift's guard-let statement:
Unlike Swift, in Kotlin, there is no guard statement at all. However, you can use the Elvis Operator – ?: for getting a similar effect.
val b: Int? = 50
fun method() {
val a = b ?: return println("Equal to 'null' or not set")
return println("Good news!")
}
method()
/* RESULT: Good news! */
there are two answers above, both got a lot acceptances:
str?.let{ } ?: run { }
str?.also{ } ?: run { }
Both seem to work in most of the usages, but #1 would fail in the following test:
#2 seems better.
Unlike Swift, Its not necessary to unwrap the optional before using it in Kotlin. We could just check if the value is non null and the compiler tracks the information about the check you performed and allows to use it as unwrapped.
In Swift:
if let a = b.val {
//use "a" as unwrapped
} else {
}
In Kotlin:
if b.val != null {
//use "b.val" as unwrapped
} else {
}
Refer Documentation: (null-safety) for more such use cases
Here's how to only execute code when name is not null:
var name: String? = null
name?.let { nameUnwrapp ->
println(nameUnwrapp) // not printed because name was null
}
name = "Alex"
name?.let { nameUnwrapp ->
println(nameUnwrapp) // printed "Alex"
}
Here's my variant, limited to the very common "if not null" case.
First of all, define this somewhere:
inline fun <T> ifNotNull(obj: T?, block: (T) -> Unit) {
if (obj != null) {
block(obj)
}
}
It should probably be internal, to avoid conflicts.
Now, convert this Swift code:
if let item = obj.item {
doSomething(item)
}
To this Kotlin code:
ifNotNull(obj.item) { item ->
doSomething(item)
}
Note that as always with blocks in Kotlin, you can drop the argument and use it:
ifNotNull(obj.item) {
doSomething(it)
}
But if the block is more than 1-2 lines, it's probably best to be explicit.
This is as similar to Swift as I could find.
There is a similar way in kotlin to achieve Swift's style if-let
if (val a = b) {
a.doFirst()
a.doSecond()
}
You can also assigned multiple nullable values
if (val name = nullableName, val age = nullableAge) {
doSomething(name, age)
}
This kind of approach will be more suitable if the nullable values is used for more than 1 times. In my opinion, it helps from the performance aspect because the nullable value will be checked only once.
source: Kotlin Discussion
I'm adding this answer to clarify the accepted answer because it's too big for a comment.
The general pattern here is that you can use any combination of the Scope Functions available in Kotlin separated by the Elvis Operator like this:
<nullable>?.<scope function> {
// code if not null
} :? <scope function> {
// code if null
}
For example:
val gradedStudent = student?.apply {
grade = newGrade
} :? with(newGrade) {
Student().apply { grade = newGrade }
}
The cleanest option in my opinion is this
Swift:
if let a = b.val {
} else {
}
Kotlin
b.val.also { a ->
} ?: run {
}
Swift if let statement in Kotlin
The short answer is use simple IF-ELSE as by the time of this comment there is no equivalent in Kotlin LET,
if(A.isNull()){
// A is null
}else{
// A is not null
}
we can get the same Unwraping syntax like Swift if let using inline fun
inline fun <T:Any?> T?.unwrap(callback: (T)-> Unit) : Boolean {
return if (this != null) {
this?.let(callback)
true
}else {
false
}
}
Uses: :
val name : String? = null
val rollNo : String? = ""
var namesList: ArrayList<String>? = null
if (name.unwrap { name ->
Log.i("Dhiru", "Name have value on it $name")
})else if ( rollNo.unwrap {
Log.i("Dhiru","Roll have value on it")
}) else if (namesList.unwrap { namesList ->
Log.i("Dhiru","This is Called when names list have value ")
}) {
Log.i("Dhiru","No Field have value on it ")
}
The problem with the Any?.let {} ?: run {} constructions is that:
It only allows for one non-null check per statement
If the let block returns null the run block is evaluated anyway
It's not possible to perform multiple checks in a switch/when style
A solution which tackles most of these problems is to define functions like the following:
private inline fun <A> ifNotNull(p1: A?, block: (A) -> Unit): Unit? {
if (p1 != null) {
return block.invoke(p1)
}
return null
}
private inline fun <A, B> ifNotNull(p1: A?, p2: B?, block: (A, B) -> Unit): Unit? {
if (p1 != null && p2 != null) {
return block.invoke(p1, p2)
}
return null
}
private inline fun <A, B, C> ifNotNull(p1: A?, p2: B?, p3: C?, block: (A, B, C) -> Unit): Unit? {
if (p1 != null && p2 != null && p3 != null) {
return block.invoke(p1, p2, p3)
}
return null
}
This would allow for a statement like:
ifNotNull(a, b) { a, b ->
// code when a, b are not null
} ?:
ifNotNull(c) { c ->
// code when a, b are null and c not null
} ?:
ifNotNull(d, e, f) { d, e, f ->
// code when a, b, c are null and d, e, f not null
} ?: run {
// code which should be performed if a, b, c, d, e and f are null
}
The only caveat is that continue and break statements are not supported if executed within a loop compared to Swift's if let equivalent.
Probably I am very late however the easiest way to unwrap and option is
yourOptionalString ?: return
this was all the following lines will have unwrapped string
If b is a member variable then this approach seems most readable to me:
val b = this.b
if (b == null) {
return
}
println("non nullable : ${b}")
This is also consistent with how it works in swift, where a new local variable shadows the member variable.