How to cast String into Int and Long? - kotlin

In Java we use
Integer.valueOf(str)
and
Long.valueOf(str)
to get the integer but how can we do the same in Kotlin?

You can just use toInt, toLong, and similar conversion extensions.
For example:
val i: Int = str.toInt()
val l: Long = str.toLong()
There's also toIntOrNull, etc. in case your strings might not be valid numbers:
val i: Int? = str.toIntOrNull()

Kotlin has extension methods for String class that do the same but more elegantly.
str.toInt()
str.toLong()
Note that you can write extension methods yourself as well.

Kotlin define extension function in StringNumberConversions.kt like toInt, toLong etc. These functions internally invoke standard java function like
java.lang.Integer.parseInt(...) or java.lang.Long.parseLong(...)
You can use them like :
"123".toInt()
"123".toLong()

These are Extension methods available for Strings to parse in KOTLIN:
str.toBoolean()
str.toInt()
str.toLong()
str.toFloat()
str.toDouble()
str.toByte()
str.toShort()

it is better to
val str = ""
val quotaInteger = str.toDouble().toInt()
cos sometime end give us like "123.22", if we use toInt(), it will throw out NumberFormatException

Related

Use ULong as function parameter in Kotlin

Can I use ULong as a parameter in function definition in Kotlin?
My code looks like below:
import androidx.compose.ui.graphics.Color
fun EColor(value: ULong) = Color(value)
val Red700 = EColor(0xffdd0d3c)
Then I got an error looks like:
Conversion of signed constants to unsigned ones is prohibited
If I call val Red700 = Color(0xffdd0d3c), then it works fine.
So how come I got this error?
There are unsigned literals in Kotlin. You write them by adding a u or U suffix:
val Red700 = EColor(0xffdd0d3cU)
You can also call toULong:
val Red700 = EColor(0xffdd0d3c.toULong())

How to skip specification of the generic type parameter in Kotlin?

This is the main body of my function
val client = ConnectionFactory.createClient() # <- Return lettice.io RedisClusterClient
val conn = client.connect()
val command = conn.sync()
var index: String? = null
index = readDataStructure(command, key)
This is my first try to define my readDataStructure function:
fun readDataStructure(command: RedisCommand, key: String): String {
...
kotlin complaints error: 3 type arguments expected for interface RedisCommand<K : Any!, V : Any!, T : Any!>
I want to be able to NOT specifying K, V and T because I am just writing a throwaway script.
Is there any Kotlin lang syntax and can allow me to just pass the command variable as is?
I suppose you are after:
fun readDataStructure(command: RedisCommand<*,*,*>, key: String): String {
?
From Kotlin docs https://kotlinlang.org/docs/tutorials/kotlin-for-py/generics.html:
If you don't have any idea (or don't care) what the generic type might be, you can use a star-projection:
fun printSize(items: List<*>) = println(items.size)
When using a generic type where you have star-projected one or more of its type parameters, you can:
Use any members that don't mention the star-projected type parameter(s) at all
Use any members that return the star-projected type parameter(s), but the return type will appear to be Any? (unless the type parameter is constrained, in which case you'll get the type mentioned in the constraint)
Not use any members that take a star-projected type as a parameter

How to create String with certain length and same value effectively in Kotlin

I knew this can be achieved with for loop but I am looking for better solution.
createDummyString(1,'A') = 'A'
createDummyString(2.'A') = 'AA'
This will be used in hangman. Thank you.
You can do it like in the example below. To learn more about Strings read this: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html
fun createDummyString(repeat : Int, alpha : Char) = alpha.toString().repeat(repeat)
Addendum:
If you want to make it more kotlinesque, you can also define repeat as extension function on Char
fun Char.repeat(count: Int): String = this.toString().repeat(count)
and call it like this:
'A'.repeat(1)
CharSequence has an extension method for this.
fun CharSequence.repeat(n: Int): String // for any whole number
Example
println("A".repeat(4)) // AAAA
println("A".repeat(0)) // nothing
println("A".repeat(-1)) // Exception
Reference : https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/repeat.html
I created a utility function using infix operator for this :
infix fun Int.times(s : CharSequence): CharSequence{
return s.repeat(this)
}
//Use like val twoAs = 2 times "A"
println(a) // AA

Generalize method with nullable arguments and return type

I have a method that converts ByteArray? to base64 String? so that if argument was null output will be null as well. This is its implementation:
fun toBase64String(array: ByteArray?): String? = if(array == null) null else
Base64.getEncoder().encodeToString(array)
But when I pass in not nullable ByteArray method returns String? which is expected. Is there a way to make it generic so such use case will be possible:
val base64 = toBase64String(ByteArray(4))
where base64 will be of type String and not String? since argument was not nullable?
I just started to work with Kotlin and probably don't know language feature that can make this possible.
You can make two overloads, one for nullable ByteArray? and one for non-null ByteArray:
fun toBase64String(array: ByteArray): String =
Base64.getEncoder().encodeToString(array)
#JvmName("toBase64StringNullable")
fun toBase64String(array: ByteArray?): String? =
if (array == null) null else toBase64String(array)
We need #JvmName("...") to avoid the declaration clash in the bytecode.
Also, this allows to distinguish the functions in Java.
Usage:
val nonNullBytes: ByteArray = TODO()
val nonNullString = toBase64String(nonNullBytes) // the inferred type is String
val nullableBytes: ByteArray? = TODO()
val nullableString = toBase64String(nullableBytes) // the inferred type is String?
When the argument is of the non-null type ByteArray, the compiler will choose the overload that returns a non-null String.
Probably overloading methods is the best solution for your case, but for the sake of completeness here are two other ways to realise that using only one method (the nullable one):
Not-Null-Asserted operator:
val base64: String = toBase64String(ByteArray(4))!!
Evlis operator:
val base64: String = toBase64String(ByteArray(4)) ?: "defaultString"
if argument was null output will be null as well
If that is the only thing the function does when it encounters null argument, it's better to declare it accepting non-null values and use safe call to deal with nulls:
fun toBase64String(array: ByteArray): String =
Base64.getEncoder().encodeToString(array)
val bytes: ByteArray? = ...
val base64 = bytes?.let { toBase64String(it) }
// the same can be written with function reference instead of lambda
val base64 = bytes?.let(::toBase64String)
Here let function is called only when bytes is not null, otherwise the result of the expression is null. When called it invokes the lambda function or the function reference specified as its argument, passing ByteArray which is already checked to be non-null to that function.
Also it can be more convenient to declare toBase64String as an extension for ByteArray, so it can be invoked with safe call without the helper function let"
fun ByteArray.toBase64String(): String =
Base64.getEncoder().encodeToString(this)
val bytes: ByteArray? = ...
val base64 = bytes?.toBase64String()

How can I use a Java String method (split) directly from Kotlin source?

Doing some profiling, it seems my bottleneck is the Kotlin kotlin.CharSequence.split() extension function.
My code just does something like this:
val delimiter = '\t'
val line = "example\tline"
val parts = line.split(delimiter)
As you might notice, parts is a List<String>.
I wanted to benchmark using Java's split directly, which returns a String[] and might be more efficient.
How can I call Java's String::split(String) directly from Kotlin source?
You can cast a kotlin.String to a java.lang.String then use the java.lang.String#split since kotlin.String will be mapped to java.lang.String , but you'll get a warnings. for example:
// v--- PLATFORM_CLASS_MAPPED_TO_KOTLIN warnings
val parts: Array<String> = (line as java.lang.String).split("\t")
You also can use the java.util.regex.Pattern#split instead, as #Renato metioned it will slower than java.lang.String#split in some situations. for example:
val parts: Array<String> = Pattern.compile("\t").split(line, 0)
But be careful, kotlin.String#split's behavior is different with java.lang.String#split , for example:
val line: String = "example\tline\t"
// v--- ["example", "line"]
val parts1: Array<String> = Pattern.compile("\t").split(line, 0)
// v--- ["example", "line", ""]
val parts2 = line.split("\t".toRegex())
You can do this:
(line as java.lang.String).split(delimiter)
But it's not recommended to not use the kotlin.String as the compiler might tell you.