顯示具有 kotlin 標籤的文章。 顯示所有文章
顯示具有 kotlin 標籤的文章。 顯示所有文章

Kotlin - apply, let, run, also, takeIf

apply: return current receiver once anonymous function complete
package examples

fun main() {
    plus(1,2).apply {
        println(this) // 3
        println(toDouble()) // 3.0
    }
}

fun plus(a: Int, b: Int): Int {
    return a + b
}

let: pass receiver to lambda you provided
package examples

fun main() {
    plus(1,2)?.let { println(it) }
}

fun plus(a: Int, b: Int): Int? {
    return a + b
}

run: Pass execution value. 
package examples

fun main() {
    val grade = 59
    grade.run(::isPassed)
            .run(::comment)
            .run(::println)
}

fun comment(passed:Boolean):String {
    if (passed) {
        return "Good job"
    } else {
        return "Oh no"
    }
}

fun isPassed(grade: Int): Boolean {
    return grade >= 60
}

also: similar to "let" with more side effect
package examples

fun main() {
    val grade = 59
    grade.run(::isPassed)
            .run{comment(this, "QQ")}
            .also(::println)
        .also{ println("$it again") }
}

fun comment(passed:Boolean, suffix:String):String {
    if (passed) {
        return "Good job$suffix"
    } else {
        return "Oh no$suffix"
    }
}

fun isPassed(grade: Int): Boolean {
    return grade >= 60
}

takeIf: Provide predicate to decide will run or not
package examples

fun main() {
    60.takeIf { isPassed(it) }?.run { println("Good Job") }
}

fun isPassed(grade: Int): Boolean {
    return grade >= 60
}


Kotlin - Numbers

Types
  • Byte
  • Short
  • Int
  • Long
  • Float
  • Double

Convert string to number
package examples

fun main() {
    println("1.01".toIntOrNull()) // null (not 1)
    println("1".toInt())
    println("1.01".toDouble())
    println("1.01".toBigDecimal())
    println("1.01e".toBigDecimal()) // NumberFormatException
}

Convert int to double
package examples

fun main() {
    val i = 1
    val d = 0.5
    println(i - d) // 0.5

    println(i.javaClass)  // int
    println(i.toDouble()) // 1.0
}

Format number to string: %
package examples

fun main() {
    println("%.2f".format(1.123456)) // 1.12
}

Convert Double to Int
package examples

import kotlin.math.roundToInt

fun main() {
    val d15 = 1.5
    val d14 = 1.4
    println(d15.roundToInt()) // 2
    println(d14.roundToInt()) // 1
    println(d15.toInt()) // 1
    println(d14.toUInt()) // 1

    val md15 = -1.5
    val md14 = -1.4
    println(md15.roundToInt()) // -1
    println(md14.roundToInt()) // -1
    println(md15.toInt()) // -1
    println(md14.toUInt()) // 0
}


Kotlin - Strings

indexOf and substring
  • indexOf
  • substring
  • split
package examples

fun main() {
    println("abc".indexOf('c'))     // 2
    println("abc".substring(1))  // bc
    println("abcdefg".substring(1 until 5)) // bcde
    println("abcdefg".substring(1 .. 5)) // bcdef
    println("a,b,c,d,e".split(",")) // [a, b, c, d, e]
    val (v1,v2,v3) = "a,b,c,d,e".split(",")
    println("$v1, $v2, $v3") // a, b, c
}

Replace with regular expression
package examples

fun main() {
    val replaceResult = "abc".replace(Regex("b"), transform = {
        when(it.value) {
            "b" -> "B"
            else -> it.value
        }
    })
    println(replaceResult) // aBc
}

Compare String
package examples

fun main() {
    val s1 = "" + "a"
    val s2 = "a"
    println(s1 == s2) // true
    println(s1 === s2) // true
}

Unicode and forEach
package examples

fun main() {
    println("\u0045") // E

    "abc".forEach { println(it) } // print a b c in separated lines
}


Kotlin - Nullable

Nullable
  • "String?" in return type shows the function may return null
  • API caller need use "?." to prevent NullPointerException
package examples

fun main() {
    println(getString(true))         // null
    println(getString(false))        // hello
    println(getString(true)?.length) // null
    println(getString(false)?.length) // 5
}

fun getString(isNull: Boolean): String? {
    if (isNull) return null
    return "hello"
}

Post action if not null
package examples

fun main() {
    println(getInt(false)?.let {
        println(it)
        it + 100
    })
}

fun getInt(isNull:Boolean): Int? {
    if (isNull) return null
    else return 5
}

Double bang operation
  • "!!." will throw exception when return value was null
package examples

fun main() {
    println(getInt(false)!!.let {
        println(it)
        it + 100
    })
    println(getInt(true)!!.let { // throw kotlin.KotlinNullPointerException due to !!.
        println(it)
        it + 100
    })
}

fun getInt(isNull:Boolean): Int? {
    if (isNull) return null
    else return 5
}

Default value if null
package examples

fun main() {
    println(getInt(true) ?: 100) // print 100
}

fun getInt(isNull:Boolean): Int? {
    if (isNull) return null
    else return 5
}

Compute differently when null and not-null
package examples

fun main() {
    // print null and kotlin.Unit because println returns Unit
    println(getInt(true) ?.and(100) ?: println("null"))
}

fun getInt(isNull:Boolean): Int? {
    if (isNull) return null
    else return 5
}


Kotlin - Anonymous Function and function type

Anonymous function
package examples

fun main() {
    var f = {
        println("hello")
    }() // print hello
}

Function type
package examples

fun main() {
    {
        println("construstor ")
    }()
    var f = {
        println("hello f1")
    }

    val f2: () -> Unit = {
        println("hello f2")
    }

    f()
    f2()
}

Implicit Return
  • Anonymous function support return last line of value
package examples
fun main() {
    var f = { //
        "implicit return"
        "ABC" // Print ABC
    }
    println(f())
}

Anonymous Function argument
package examples

fun main() {
            // arg types                return type   arg names
    val f : (String, String, String) -> Int =         {a, b, c ->
        a.length + b.length + c.length
    }
    println(f("aa", "fff", "ee"))
}

Default argument name: it
  • "it" is the default argument name when there is only one parameter in anonymous function
package examples

fun main() {
    val f : (String) -> Int = {
        it.length
    }
    println(f("Gss"))
}

Return type inference
  • No need to specify return type
package examples

fun main() {
    val f = {
        "hello"
    }
    println(f())
}
  • Need provide arg name when no return type specified
package examples

fun main() {
    val f = { name:String ->
        "hello $name"
    }
    println(f("FF"))
}

Function as argument
package examples

fun main() {
    println(count("hello", {it == 'l'}))
}

fun count(s:String, exclude:(Char) -> Boolean): Int {
    var result = 0
    for (c in s) if (!exclude(c)) result++
    return result
}
  • Lambda argument should be moved out of parentheses (Intellij suggestion)
    (When function is the latest argument)
package examples

fun main() {
    println(count("hello") {it == 'l'})
}

fun count(s:String, exclude:(Char) -> Boolean): Int {
    var result = 0
    for (c in s) if (!exclude(c)) result++
    return result
}

Function Inlining
  • Inlining removes the need for the JVM to use an object instance and to perform variable memory allocations for the lambda.
package examples

fun main() {
    println(count("hello") {it == 'l'})
}

inline fun count(s:String, exclude:(Char) -> Boolean): Int {
    var result = 0
    for (c in s) if (!exclude(c)) result++
    return result
}

Function Reference
  • Use "::" to reference a function
package examples

fun main() {
    run(::printHello)
}

fun run(f: () -> Unit) {
    f()
}

fun printHello() {
    println("hello")
}

Return Function Type
package examples

fun main() {
    create()("john")
}

fun create(): (String) -> Unit {
    return {
        println("hello $it")
    }
}


Kotlin - Functions Basic

  • Function parameter is read-only

Ex. Private function (Default is public)
package examples

fun main() {
    val i = 100
    printS(i)
    println(publicPrint(i))
}

fun publicPrint(i: Int):String {
    return when(i) {
        in 0..100 -> "0-100"
        else -> "else"
    }
}

private fun printS(i: Int) {
    return when(i) {
        in 0..100 -> println("0-100")
        else -> println("else")
    }
}

Default parameter value
package examples

fun main() {
    printNumber(50) // print 50
    printNumber() // print 100
}

fun printNumber(n: Int = 100) {
    println(n)
}

One line function
package examples

fun main() {
    printNumber(50) // print 50
    printNumber() // print 100
}

fun printNumber(n: Int = 100) = println(n)

Named argument
package examples

fun main() {
    printABC(1,2,3) // print 1,2,3
    printABC(c=1, a=2, b=3)  // print 2,3,1
}

fun printABC(a:Int,b:Int,c:Int) {
    println("a=$a, b=$b, c=$c")
}

Unit type and Nothing type
  • Unit type is same as void in Java
  • Nothing type is same as throwing UnSupportedException in Java
package examples

fun main() {
    val u1 : Unit = printABC(1,2,3) // print 1,2,3
    val u2 : Unit = printABC(c=1, a=2, b=3)  // print 2,3,1
    println(u1) // Print kotlin.Unit
    println(u2) // Print kotlin.Unit
    notImplemented()
    println("No reachable") // won't be printed
}

fun notImplemented(): Nothing = throw NotImplementedError()

fun printABC(a:Int,b:Int,c:Int) {
    println("a=$a, b=$b, c=$c")
}
Output
a=1, b=2, c=3
a=2, b=3, c=1
kotlin.Unit
kotlin.Unit
Exception in thread "main" kotlin.NotImplementedError: An operation is not implemented.
    at examples.HelloKt.notImplemented(Hello.kt:11)
    at examples.HelloKt.main(Hello.kt:8)
    at examples.HelloKt.main(Hello.kt)

Process finished with exit code 1

Backticks function name
  • It's for Java and Kotlin reserved words conflict solution
  • It's useful when writing unit test code
package examples

fun main() {
    `this is a book test`()
}

fun `this is a book test`() {
    println("assert this is a book")
}

File-level variable
examples/MyNumber.kt
package examples

const val MAX = 10000

examples/Hello.ky
package examples

// const val MAX = 30 // can't declare MAX twice under the same package
fun main() {
    println(MAX) // don't need specify
}

example2/MyNumber2.kt
package example2

const val MAX = 4000 // can use same name as examples/MyNumber.kt
const val MAX2 = examples.MAX // can reference another packages constant


Kotlin String Template

  • until
  • downTo
  • Compare by char
  • Convert to list
package examples

fun main() {
    val age = 100
    if (age in 150 downTo 0) {
        println("downTo")
    }
    if (age in 0 until 100) {
        println("until")
    }
    val c = 'X'
    val s = c in 'a'..'q'
    println(s)


    val downToList = (10 downTo 0).toList()
    println(downToList)


    val untilList = (0 until 10).toList()
    println(untilList)


    val b = false
    val ss = "${if(b) "Yes" else "No"}"
    println(ss)
}


kotlin - when

When
package examples

fun main() {
    var name = "John"
    val greet = when(name) {
        "John" -> "Hello John"
        else -> "Unknown"
    }
    println(greet)
}

When + if else
package examples

fun main() {
    val i = 50
    val s = when(i) {
        in 0..50 -> "0-50"
        in 51..100 -> "51-100"
        else -> if (i in 101..150) "101-150" else "Out Of Range"
    }
}


Kotlin - if-else and comparing

if-else
package examples

fun main() {
    var n = 0
    if (n > 0) {
        println("> 0")
    } else if (n == 0) {
        println("== 0")
    } else {
        println("< 0")
    }
}


if in range
package examples

fun main() {
    var r = 100
    if (r in 10..50) {
        println("0-50")
    } else if (r in 50..100) {
        println("50-100") // print this
    } else {
        println("> 100")
    }
}

Conditional Expression - With braces
package examples

fun main() {
    var success = true
    var s = if (success) {
        "Good"
    } else {
        "Bad"
    }
    println(s)
}

Conditional Expression - No braces
package examples

fun main() {
    var success = true
    var s = if(success) "Good" else "Bad"
    println(s)
}

Conditional Expression - No braces wrap line
package examples

fun main() {
    var r = 100
    var s = if (r < 60) "< 60"
            else if (r == 60) "60"
            else "> 60"
    println(s)
}

Conditional Expression - No braces with nested if-else
package examples

fun main() {
    var r = 100
    val s = if (r < 60)
                if (r < 30) "0 ~ 30"
                else "30-60"
            else if (r == 60) "60"
            else "> 60"
    println(s)
}

Compare
package examples

fun main() {
    var s1 = setOf("a")
    var s2 = setOf("a")

    // value is the same
    println(s1 == s2) // true
    println(s1 != s2) // false

    // reference is different
    println(s1 === s2) // false
    println(s1 !== s2) // true
}


Kotlin - Hello World, Define variable and const

Hello.kt
fun main(args: Array<String>) {  
   println("Hello, world!")
}

Define variable
package examples

fun main(args: Array<String>) {
    // variable type declaration
    var i = 0;
    var i2: Int = 0
    println("hwllo " + ++i + ++i2)

    // can skip type declaration
    var s = "string"
    println("string: " + s)

    var c : Char = 'a'
    println("Char" + c)

    var b = true
    var d = 0.123
    var list = listOf("a","b","c")
    println(list)

    var set : Set<String> = setOf("d","e", "f", "d")
    println(set)

    var map = mapOf("a" to 1, "b" to 2)
    println(map)

    // read only => val
    val pp = i
    println(pp)
}

Declare const
package examples

const val MAX = 100

fun main() {
    // const can't be declared within method
//    const val MAX = 100
    println(MAX)
}





別名演算法 Alias Method

 題目 每個伺服器支援不同的 TPM (transaction per minute) 當 request 來的時候, 系統需要馬上根據 TPM 的能力隨機找到一個適合的 server. 雖然稱為 "隨機", 但還是需要有 TPM 作為權重. 解法 別名演算法...