Kotlin学习三:高阶函数

目录

一、高阶函数的基本概念

二、常见高阶函数

1、关于list映射

2、flatMap

3、综合1

4、综合2

三、尾递归优化

四、闭包

五、函数复合

六、科理化

七、偏函数

八、小案例


一、高阶函数的基本概念

 

class Hello {
    fun world() {
        println("Hello World")
    }
}

class PdfPrinter {
    fun print(any: Any) {
        kotlin.io.print(any)
    }
}

fun main(args: Array<String>) {
    val mList: List<Int> = listOf(1, 3, 5, 7, 9)
    println(mList)

    val mList2: List<String> = arrayListOf("1", "2", "5")
    println(mList2)

    val mArray: Array<String> = arrayOf("2", "5", "8")
    mArray.forEach { print(it) }
    println()
    mArray.forEach(::print)
    println()

    Hello::world
    val helloWorld = Hello::world
    println(helloWorld)

    val hello = Hello()
    hello.world()

    mArray.filter(String::isNotEmpty)

    val pdfPrinter = PdfPrinter()
    mArray.forEach (pdfPrinter::print)
}

二、常见高阶函数

forEach,map,flatmap,fold,reduce,filter,takeWhile,let,apply,with,use

1、关于list映射

fun main(args: Array<String>) {
    javaMethodWriting()
    println()
    kotlinMethodWriting()
}

fun kotlinMethodWriting() {
    val list = listOf(1, 2, 3, 4)

    val newList = list.map {
        it * 2 + 1
    }

    val newList2 = list.map {
        it.toDouble()
    }

    val newList3 = list.map(Int::toDouble)

    newList.forEach(::print)
    println()
    newList2.forEach(::print)
}

fun javaMethodWriting() {
    val list = listOf(1, 2, 3, 4)

    val newList = ArrayList<Int>()

    list.forEach {
        val newElement = it * 2 + 1
        newList.add(newElement)
    }

    newList.forEach(::print)
}

2、flatMap

fun main(args: Array<String>) {
    val list = listOf(
            10..15,
            5..10,
            40..45
    )

    // [1,2,...,20,30,...,50,10,100,...,200]
    val flatList = list.flatMap { it }

//    flatList.forEach(::println)

    val flatList2 = list.flatMap {
        it.map {
            "No. $it"
        }
    }

    //以上等价于
    val flatList3 = list.flatMap { intRange ->
        intRange.map { intElement ->
            "No. $intElement"
        }
    }


    flatList2.forEach(::println)
}

3、综合1

fun main(args: Array<String>) {
    val list = listOf(
            10..15,
            5..10,
            40..45
    )

    // [1,2,...,20,30,...,50,10,100,...,200]
    val flatList = list.flatMap { it }

//    flatList.forEach(::println)
    //reduce
//    println(flatList.reduce { acc, i -> acc + i })

    //求阶乘,并把阶乘打印出来
//    (0..6).map(::factorial).forEach(::println)

//    println((0..6).map(::factorial).fold(StringBuilder()){ acc, i ->
//            acc.append(i).append(", ")
//    })
//
//    println((0..6).map(::factorial).foldRight(StringBuilder()){i, acc ->
//            acc.append(i).append(", ")
//    })
//
//    println((0..6).joinToString(", "))

    println((0..6).map(::factorial))

    //获取奇数
    println((0..6).map(::factorial).filter { it % 2 == 1 })

    //获取奇数位的结果
    println((0..6).map(::factorial).filterIndexed { index, i -> index % 2 == 1 })

    //遇到奇数就获取,直到非奇数就停止(即直到不符合条件的就停止)
    println((0..6).map(::factorial).takeWhile { it % 2 == 1 })


    val flatList2 = list.flatMap {
        it.map {
            "No. $it"
        }
    }

    //以上等价于
    val flatList3 = list.flatMap { intRange ->
        intRange.map { intElement ->
            "No. $intElement"
        }
    }
//    flatList2.forEach(::println)

}

//求阶乘
fun factorial(n: Int): Int {
    if (n == 0) return 1
    return (1..n).reduce { acc, i -> acc * i }
}

4、综合2

data class Person(val name: String, val age: Int) {
    fun work() {
        println("$name is working!!!")
    }
}


fun main(args: Array<String>) {
//    val person = findPerson()
//    println(person?.name)
//    println(person?.age)

//    findPerson()?.let { person ->
//        println(person.name)
//        println(person.age)
//        person.work()
//    }
//
//    findPerson()?.apply {
//        println(name)
//        println(age)
//        work()
//    }

//    val br = BufferedReader(FileReader("hello.txt"))
//    with(br) {
//        var line: String?
//        while (true) {
//            line = readLine() ?: break
//            println(line)
//        }
//        close()
//    }

//    val br = BufferedReader(FileReader("hello.txt")).readText()
//    println(br)

    BufferedReader(FileReader("hello.txt")).use {
        var line: String?
        while (true) {
            line = it.readLine() ?: break
            println(line)
        }
    }


}

fun findPerson(): Person? {
    return null
}

三、尾递归优化

data class ListNode(val value: Int, var next: ListNode? = null)

tailrec fun findListNode(head: ListNode?, value: Int): ListNode? {
    head ?: return null
    if (head.value == value) return head
    return findListNode(head.next, value)
}

//如果去掉 tailrec 就会报StackOverflowError
fun main(args: Array<String>) {
    val MAX_NODE_COUNT = 100000
    val head = ListNode(0)
    var p = head
    for (i in 1..MAX_NODE_COUNT) {
        p.next = ListNode(i)
        p = p.next!!
    }

    println(findListNode(head, MAX_NODE_COUNT - 2)?.value)
}

fun factorial(n: Long): Long {
    return n * factorial(n - 1)
}

data class TreeNode(val value: Int) {
    var left: TreeNode? = null
    var right: TreeNode? = null
}

fun findTreeNode(root: TreeNode?, value: Int): TreeNode? {
    root ?: return null
    if (root.value == value) return root
    return findTreeNode(root.left, value) ?: return findTreeNode(root.right, value)
}

四、闭包

val string = "HelloWorld"

fun makeFun(): () -> Unit {
    var count = 0
    return fun() {
        println(++count)
    }
}

fun fibonacci(): Iterable<Long> {
    var first = 0L
    var second = 1L
    return Iterable {
        object : LongIterator() {
            override fun nextLong(): Long {
                val result = second
                second += first
                first = second - first
                return result
            }

            override fun hasNext() = true
        }
    }
}

fun main(args: Array<String>) {
//    val x = makeFun()
//    x()
//    x()
//    x()

    for (i in fibonacci()) {
        if (i > 100) break
        println(i)
    }


//    val add5 = add(5)
//    println(add5(2))
}

//fun add(x: Int) = fun(y: Int) = x + y

fun add(x: Int): (Int) -> Int {
    data class Person(val name: String, val age: Int)

    return fun(y: Int): Int {
        return x + y
    }
}

 

五、函数复合(f(g(x)),infix)

//f(g(x))   m(x) = f(g(x))
val add5 = {i: Int -> i + 5} // g(x)
val multiplyBy2 = {i : Int -> i * 2} // f(x)

fun main(args: Array<String>) {
    println(multiplyBy2(add5(8))) // (5 + 8) * 2

    val add5AndMultiplyBy2 = add5 andThen multiplyBy2
    val add5ComposeMultiplyBy2 = add5 compose  multiplyBy2
    println(add5AndMultiplyBy2(8)) // m(x) = f(g(x))     // (5 + 8) * 2
    println(add5ComposeMultiplyBy2(8)) // m(x) = g(f(x))   // 8 * 2 + 5
}

//P1, P2,是参数值   R是返回值
infix fun <P1, P2, R> Function1<P1, P2>.andThen(function: Function1<P2, R>): Function1<P1,R>{
    return fun(p1: P1): R{
        return function.invoke(this.invoke(p1))
    }
}

infix fun <P1,P2, R> Function1<P2, R>.compose(function: Function1<P1, P2>): Function1<P1, R>{
    return fun(p1: P1): R{
        return this.invoke(function.invoke(p1))
    }
}

 

六、科理化(Currying)-函数调用链

fun log(tag: String, target: OutputStream, message: Any?){
    target.write("[$tag] $message\n".toByteArray())
}

//fun log(tag: String)
//    = fun(target: OutputStream)
//    = fun(message: Any?)
//    = target.write("[$tag] $message\n".toByteArray())

fun main(args: Array<String>) {
    log("benny", System.out, "HelloWorld")
//    log("benny")(System.out)("HelloWorld Again.")
    ::log.curried()("benny")(System.out)("HelloWorld Again.")

    val consoleLogWithTag = (::log.curried())("benny")(System.out)
    consoleLogWithTag("HelloAgain Again.")
    consoleLogWithTag("HelloAgain Again.")
    consoleLogWithTag("HelloAgain Again.")
    consoleLogWithTag("HelloAgain Again.")

    val bytes = "我是中国人".toByteArray(charset("GBK"))
    val stringFromGBK = makeStringFromGbkBytes(bytes)
}

fun <P1, P2, P3, R> Function3<P1, P2, P3, R>.curried()
    = fun(p1: P1) = fun(p2: P2) = fun(p3: P3) = this(p1, p2, p3)

val makeString = fun(byteArray: ByteArray, charset: Charset): String{
    return String(byteArray, charset)
}

val makeStringFromGbkBytes = makeString.partial2(charset("GBK"))


fun <P1, P2, R> Function2<P1, P2, R>.partial2(p2: P2) = fun(p1: P1) = this(p1, p2)
fun <P1, P2, R> Function2<P1, P2, R>.partial1(p1: P1) = fun(p2: P2) = this(p1, p2)

 

七、偏函数

代码见上

八、小案例

fun main(args: Array<String>) {
    val map = HashMap<Char, Int>()
    File("build.gradle").readText().toCharArray().filterNot(Char::isWhitespace)
            .groupBy { it }.map {
        it.key to it.value.size
    }.forEach(::println)

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值