Kotlin学习手记——集合变换,多线程高并发


public inline fun <T, R, V> Iterable<T>.zip(other: Array<out R>, transform: (a: T, b: R) -> V): List<V> {

    val arraySize = other.size

    val list = ArrayList<V>(minOf(collectionSizeOrDefault(10), arraySize))

    var i = 0

    for (element in this) {

        if (i >= arraySize) break

        list.add(transform(element, other[i++]))

    }

    return list

} 

集合变换应用例子:

统计文本文件中非空格字符出现的次数


import java.io.File



fun main() {

    File("build.gradle").readText() // 1. read file

        .toCharArray() // 2.

        //.filter{ !it.isWhitespace() } // 3. filter white space

        .filterNot(Char::isWhitespace) // 等价上面一行

        .groupBy { it } //分组

        .map {

            it.key to it.value.size

        }.let {

            println(it)

        }

} 

SAM转换

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


 val executor: ExecutorService = Executors.newSingleThreadExecutor()



    //匿名内部类的写法

    executor.submit(object : Runnable {

        override fun run() {

            println("run in executor.")

        }

    })



    //匿名内部类简写

    executor.submit(Runnable {

        println("run in executor.")

    })



    //匿名内部类简写

    executor.submit { println("run in executor.") } 

kotlin中SAM目前只支持只有一个方法的java接口


fun submitRunnable(runnable: Runnable){

    runnable.run()

}



submitRunnable {

    println("Hello")

} 

kotlin中SAM不支持只有一个方法的kotlin接口, 但是可以直接定义一个函数参数

下面这样写法是不行的:


interface Invokable {

    fun invoke()

}



fun submit(invokable: Invokable) {

    invokable.invoke()

}

//报错

submit {

    println("Hello")

} 

下面这样写法是可行的:


typealias FunctionX = ()->Unit

//函数参数传递一个lambda表达式

fun submit(block: FunctionX){

    block()

}

//等价这种直接传lambda表达式的写法

//fun submit(()->Unit){

//

//}

 //这样是可以的

 submit {

     println("Hello啊啊啊")

 } 

在这里插入图片描述

一个例子,添加和移除监听的正确kotlin写法:


public class EventManager {

    interface OnEventListener {

        void onEvent(int event);

    }



    private HashSet<OnEventListener> onEventListeners = new HashSet<>();



    public void addOnEventListener(OnEventListener onEventListener){

        this.onEventListeners.add(onEventListener);

    }



    public void removeOnEventListener(OnEventListener onEventListener){

        this.onEventListeners.remove(onEventListener);

    }

} 

使用上面的java类:


fun main() {

    val eventManager = EventManager()

    //匿名内部类的写法

    val onEvent = EventManager.OnEventListener { event -> println("onEvent $event") }

    //等价上面的写法

    val onEvent2 = object : EventManager.OnEventListener{

        override fun onEvent(event: Int) {

            println("onEvent $event")

        }

    }

    // DO NOT use this. 

    //错误的写法,这样还是一个函数类型,传到removeOnEventListener方法里不能移除,

    // 还是会调用方法创建一个对象

//    val onEvent3 = { event: Int ->

//        println("onEvent $event")

//    }

    eventManager.addOnEventListener(onEvent)

    eventManager.removeOnEventListener(onEvent)

} 

DSL: 领域特定语言

如sql语言、gradle中的groovy语言等,kotlin可以方便的实现这些语言的写法

例子: 通过拼接操作生成一个html文件


import java.io.File



interface Node {

    fun render(): String

}



class StringNode(val content: String): Node {

    override fun render(): String {

        return content

    }

}



class BlockNode(val name: String): Node {



    val children = ArrayList<Node>()

    val properties = HashMap<String, Any>()



    override fun render(): String {

        return """<$name ${properties.map { "${it.key}='${it.value}'" }.joinToString(" ")}>${children.joinToString(""){ it.render() }}</$name>"""

    }



    operator fun String.invoke(block: BlockNode.()-> Unit): BlockNode {

        val node = BlockNode(this)

        node.block()

        this@BlockNode.children += node

        return node

    }



    operator fun String.invoke(value: Any) {

        this@BlockNode.properties[this] = value

    }



    operator fun String.unaryPlus(){

        this@BlockNode.children += StringNode(this)

    }



}



fun html(block: BlockNode.() -> Unit): BlockNode {

    val html = BlockNode("html")

    html.block()

    return html

}



fun BlockNode.head(block: BlockNode.()-> Unit): BlockNode {

    val head = BlockNode("head")

    head.block()

    this.children += head

    return head

}



fun BlockNode.body(block: BlockNode.()-> Unit): BlockNode {

    val head = BlockNode("body")

    head.block()

    this.children += head

    return head

}



fun main() {

    //变量后面跟东西相当于传递一个lambda表达式

    val htmlContent = html {

        head {

            "meta" { "charset"("UTF-8") } //字符串后面跟东西相当于运算符重载 invoke

        }

        body {

            "div" {

                "style"(

                    """

                    width: 200px; 

                    height: 200px; 

                    line-height: 200px; 

                    background-color: #C9394A;

                    text-align: center

                    """.trimIndent()

                )

                "span" {

                    "style"(

                        """

                        color: white;

                        font-family: Microsoft YaHei

                        """.trimIndent()

                    )

                    +"Hello HTML DSL!!"

                }

            }

        }

    }.render()



    File("Kotlin.html").writeText(htmlContent)

} 

这个例子主要有两点:

  • 一个是如果是变量后面跟东西相当于传递一个lambda表达式,那定义的时候其实就是定义一个函数来实现;

  • 二是如果字符串后面跟l东西相当于运算符重载 invoke,跟{}相当于参数是一个ambda表达式,跟()就是普通参数,定义String类的扩展函数即可实现。


 operator fun String.invoke(block: BlockNode.()-> Unit): BlockNode {

        val node = BlockNode(this)

        node.block()

        this@BlockNode.children += node

        return node

    }



    operator fun String.invoke(value: Any) {

        this@BlockNode.properties[this] = value

    } 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kotlin 中,可以使用协程来处理多线程并发问题。协程是一种轻量级的线程,它不需要像传统的线程那样占用操作系统的资源,而是通过挂起和恢复的方式来实现并发。在协程中,可以使用 `suspend` 关键字来定义一个挂起函数,该函数可以在需要挂起的地方使用 `delay()` 函数来等待一段时间,或者使用 `withContext()` 函数来切换到其他线程执行一些耗时操作。 下面是一个使用协程处理多线程并发的示例代码: ```kotlin import kotlinx.coroutines.* fun main() = runBlocking { // 定义一个协程作用域 coroutineScope { // 启动两个协程,分别执行耗时操作 val job1 = launch { println("job1 start") delay(1000) println("job1 end") } val job2 = launch { println("job2 start") delay(500) println("job2 end") } // 等待两个协程执行完成 job1.join() job2.join() // 执行完成后输出结果 println("all jobs done") } } ``` 在这个示例中,我们使用了 `coroutineScope` 函数来定义了一个协程作用域,然后在该作用域中启动了两个协程,分别执行了一些耗时操作。在启动协程时,我们使用了 `launch` 函数来定义一个协程,其中使用了 `delay` 函数来模拟一些耗时操作。最后,我们使用了 `join` 函数来等待两个协程执行完成,然后输出一个完成的消息。 总之,使用 Kotlin 的协程可以很方便地处理多线程并发问题,它提供了一种简单、轻量级的并发编程方式。需要注意的是,在使用协程时,需要使用 `runBlocking` 函数来启动一个协程作用域,以确保协程能够正常工作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值