天天看点

Kotlin常用的高阶函数(Filter、TakeWhile、Let、Apply、With......)

一、Filter

package net.println.kotlin.chapter5.builtins

/**
 * @author:wangdong
 * @description:Kotlin常见的高阶函数
 */

fun main(args: Array<String>) {

    //求(0..6)的阶乘
    (0..6).map(::factorial).forEach(::println)
    //阶乘过滤,只要阶乘是奇数的
    //public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
    //    return filterTo(ArrayList<T>(), predicate)
    //}
    println((0..6).map(::factorial).filter { it % 2 == 1 })  //[1, 1]
    //要处于奇数位上的阶乘
    println((0..6).map(::factorial).filterIndexed{ index, i ->  index % 2 == 1 })   //[1, 6, 120]
}

/**reduce求阶乘*/
//一个正整数的阶乘(英语:factorial)是所有小于及等于该数的正整数的积,并且有0的阶乘为1。 自然数n的阶乘写作n!。
//例如3的阶乘:1*2*3 = 6
fun factorial(n: Int): Int{
    if (n == 0)return 1
    //如果n >0,本次的acc*下一次的acc
    return (1..n).reduce{acc,i -> acc * i}
}           

二、TakeWhile

package net.println.kotlin.chapter5.builtins

/**
 * @author:wangdong
 * @description:Kotlin常见的高阶函数
 */

fun main(args: Array<String>) {

    //求(0..6)的阶乘
    (0..6).map(::factorial).forEach(::println)
    //1
    //1
    //2
    //6
    //24
    //120
    //720

    //现在一个程序是,要按照顺序取数,遇到不符合要求的,程序就停止,例如遇到第一个偶数就停止
    println((0..6).map(::factorial).takeWhile { it % 2 == 1 })  //[1, 1]
}

/**reduce求阶乘*/
//一个正整数的阶乘(英语:factorial)是所有小于及等于该数的正整数的积,并且有0的阶乘为1。 自然数n的阶乘写作n!。
//例如3的阶乘:1*2*3 = 6
fun factorial(n: Int): Int{
    if (n == 0)return 1
    //如果n >0,本次的acc*下一次的acc
    return (1..n).reduce{acc,i -> acc * i}
}           

三、Let的使用

package net.println.kotlin.chapter5.builtins


/**
 * @author:wangdong
 * @description:Kotlin常见的高阶函数
 */

fun main(args: Array<String>) {

    //let的使用
    findPerson() ?.let { persion ->
        persion.work()
    }
    //王栋 is working!!!
}

/**定义一个Person类*/
data class Person(var name:String, var age: Int){
    fun work(){
        println("$name is working!!!")
    }
}

fun findPerson(): Person ?{
    return Person("王栋",23)
}           

四、Apply

package net.println.kotlin.chapter5.builtins
/**
 * @author:wangdong
 * @description:Kotlin常见的高阶函数
 */

fun main(args: Array<String>) {

    /**
     * Calls the specified function [block] with `this` value as its receiver and returns `this` value.
     */
    /*@kotlin.internal.InlineOnly
    public inline fun <T> T.apply(block: T.() -> Unit): T {
        contract {
            callsInPlace(block, InvocationKind.EXACTLY_ONCE)
        }
        block()
        return this
    }*/
    //apply的使用,可以直接调用work()方法,可以使用Persion中的成员变量
    findPerson() ?.apply {
        work()
        print(age)
    }

}

/**定义一个Person类*/
data class Person(var name:String, var age: Int){
    fun work(){
        println("$name is working!!!")
    }
}

fun findPerson(): Person ?{
    return Person("王栋",23)
}           

五、With和Apply的区别

With用来传参、Apply用来调用

/**
 * Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return receiver.block()
}

/**
 * Calls the specified function [block] with `this` value as its receiver and returns `this` value.
 */
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}           

六、两种方式读文件内容

package net.println.kotlin.chapter5.builtins

import java.io.BufferedReader
import java.io.FileReader


/**
 * @author:wangdong
 * @description:Kotlin常见的高阶函数
 */

fun main(args: Array<String>) {

    //1.推荐的输出方式
    val br = BufferedReader(FileReader("hello.txt")).readText()
    println(br)
    /*2.同样可以输出
    with(br){
        var line: String?
        while (true){
            line = readLine() ?: break
            println(line)
        }
        close()
    }*/

    //hello 王栋
}           

七、Use

看看Use的源码

/**
 * Executes the given [block] function on this resource and then closes it down correctly whether an exception
 * is thrown or not.
 *
 * @param block a function to process this [Closeable] resource.
 * @return the result of [block] function invoked on this resource.
 */
@InlineOnly
@RequireKotlin("1.2", versionKind = RequireKotlinVersionKind.COMPILER_VERSION, message = "Requires newer compiler version to be inlined correctly.")
public inline fun <T : Closeable?, R> T.use(block: (T) -> R): R {
    var exception: Throwable? = null
    try {
        return block(this)
    } catch (e: Throwable) {
        exception = e
        throw e
    } finally {
        when {
            apiVersionIsAtLeast(1, 1, 0) -> this.closeFinally(exception)
            this == null -> {}
            exception == null -> close()
            else ->
                try {
                    close()
                } catch (closeException: Throwable) {
                    // cause.addSuppressed(closeException) // ignored here
                }
        }
    }
}           

八、Use的小例子

package net.println.kotlin.chapter5.builtins

import java.io.BufferedReader
import java.io.FileReader


/**
 * @author:wangdong
 * @description:Kotlin常见的高阶函数
 */

fun main(args: Array<String>) {

    //1.推荐的输出方式
    val br = BufferedReader(FileReader("hello.txt")).use {
        var line: String?
        while (true) {
            line = it.readLine() ?: break
            println(line)
        }
    }
    //hello 王栋
}           

好了,结束了!