Kotlin(3)-协程和操作符重载,金三银四Java高级工程师面试题整理
2021/9/6 14:07:21
本文主要是介绍Kotlin(3)-协程和操作符重载,金三银四Java高级工程师面试题整理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
for (i in 0..10) { println("异步请求正在执行:getToken :$i") delay(100) } return "ask"
}
suspend fun getResponse(token: String): String {
for (i in 0…10) {
println(“异步请求正在执行:getResponse :$token $i”)
delay(100)
}
return "response"
}
fun setText(response: String) {
println(“setText 执行,时间: ${System.currentTimeMillis()}”)
}
fun main() {
GlobalScope.launch(Dispatchers.Unconfined) {
var token = GlobalScope.async(Dispatchers.Unconfined) {
return@async getToken()
}.await() // 创建异步任务,并且 阻塞执行 await 是阻塞执行取得结果
var response = GlobalScope.async(Dispatchers.Unconfined) { return@async getResponse(token) }.await() // 创建异步任务,并且立即执行 setText(response) } Thread.sleep(20000)
}
执行结果: ```kotlin 异步请求正在执行:getToken :0 异步请求正在执行:getToken :1 异步请求正在执行:getToken :2 异步请求正在执行:getToken :3 异步请求正在执行:getToken :4 异步请求正在执行:getToken :5 异步请求正在执行:getToken :6 异步请求正在执行:getToken :7 异步请求正在执行:getToken :8 异步请求正在执行:getToken :9 异步请求正在执行:getToken :10 异步请求正在执行:getResponse :ask 0 异步请求正在执行:getResponse :ask 1 异步请求正在执行:getResponse :ask 2 异步请求正在执行:getResponse :ask 3 异步请求正在执行:getResponse :ask 4 异步请求正在执行:getResponse :ask 5 异步请求正在执行:getResponse :ask 6 异步请求正在执行:getResponse :ask 7 异步请求正在执行:getResponse :ask 8 异步请求正在执行:getResponse :ask 9 异步请求正在执行:getResponse :ask 10 setText 执行,时间: 1578904290520
-
当前正在执行一项异步任务,但是你突然不想要它执行了,随时可以取消
fun main() { // 协程任务 val job = GlobalScope.launch(Dispatchers.IO) { for (i in 0..100){// 每次挂起100MS,100次也就是10秒 println("协程正在执行 $i") delay(100) } } // 但是我在1秒之后就取消协程 Thread.sleep(1000) job?.cancel() println( "btn_right 结束协程") }
执行结果(本该执行100轮的打印,只持续了10轮):
协程正在执行 0 协程正在执行 1 协程正在执行 2 协程正在执行 3 协程正在执行 4 协程正在执行 5 协程正在执行 6 协程正在执行 7 协程正在执行 8 协程正在执行 9 btn_right 结束协程 Process finished with exit code 0
-
如果你想让一个任务最多执行3秒,超过3秒则自动取消
import kotlinx.coroutines.* fun main() = runBlocking { println("限时任务中结果是:" + getResFromTimeoutTask()) } suspend fun getResFromTimeoutTask(): String? { // 忘了,它会保证内部的协程代码都执行完毕,所以不能这么写 return withTimeoutOrNull(1300) { for (i in 0..10) { println("I'm sleeping $i ...") delay(500) } "执行结束" } }
执行结果
I'm sleeping 0 ... I'm sleeping 1 ... I'm sleeping 2 ... 限时任务中结果是:null Process finished with exit code 0
总结
协程作为kotlin 区别于java的新概念,它的出现是为了解决java不好解决的问题,比如层层回调导致代码臃肿,比如 异步任务执行流程不好操控等。本章节篇幅有限,无法展开说明,但是对于新手而言,看完本章应该能对协程的作用有一个大概的认知。本人也是初步研究,后续有更深入的了解之后,再进行专文讲解吧。
操作符重载
概念
说人话,像是一元操作符 ++自加,二元操作符 +相加 ,默认只支持数字类型,比如Int. 但是通过操作符的重载,我们可以让任意类 都能 ++自加,且返回一个想要的对象。操作符执行的逻辑,完全看我们如何去设计。
分类
按元素级别
-
一元
表达式 对应函数 +a a.unaryPlus() -a a.unaryMinus() !a a.not() a++ a.inc() a– a.dec() -
二元
表达式 对应函数 a+b a.plus(b) a-b a.minus(b) a*b a.times(b) a/b a.div(b) a%b a.rem(b) a…b a.range(b) a in b b.contains(a) a !in b !b.contains(a) a[i] a.get(i) a[i,j] a.get(i,j) a[i_1,…,i_n] a.get(i_1,…,i_n) a[i]=b a.set(i,b) a[i,j]=b a.set(i,j,b) a[i_1,…,i_n]=b a.set(i_1,…,i_j,b) a() a.invoke() a(i) a.invoke(i) a(i,j) a.invoke(i,j) a(i_1,…,i_n) a.invoke(i_1,…,i_n) a+=b a.plusAssign(b) a-=b a.minusAssign(b) a*=b a.timesAssign(b) a/=b a.divAssign(b) a%=b a.modAssign(b) a > b a.compareTo(b)>0 a < b a.compareTo(b)<0 a>=b a.compareTo(b)>=0 a<=b a.compareTo(b)<=0
按实现方式
-
成员函数
-
扩展函数
栗子
看到上面的一大堆,肯定有点懵,看个例子解决疑问。上面我用两种维度来对操作符重载进行了分类,那么,先试试:成员函数的方式来重载一个一元操作符
class A(i: Int, j: Int) { var i: Int = i var j: Int = j /** * 重载++操作 */ operator fun inc(): A { return A(i++, j++) } override fun toString(): String { return "[i=$i , j=$j]" } }
如上代码,注意看:
operator fun inc(): A { return A(i++, j++) }
Kotlin的操作符重载和 c++,dart语言内的操作符重载写法完全不同,它不再是直接把操作符放到了 重写的过程中,而是每一种支持重载的操作符都有一个对应的 函数名
正如:上表格中的 a++ 操作符,对应的函数就是 a.inc()
调用的时候:
fun main() { var a = A(1, 2) println("a:$a") println("a++:${a++}") }
打印结果:
a:[i=1 , j=2] a++:[i=2 , j=3]
再看一个二元运算符重载的栗子,这次我们不用成员函数,而是用扩展函数:
class A(i: Int, j: Int) { var i: Int = i var j: Int = j override fun toString(): String { return "[i=$i , j=$j]" } } /** * 重载A类的 x+y 操作 */ operator fun A.plus(a: A): A { return A(this.i + a.i, this.j + a.j) } fun main() { val x = A(1,1) val y = A(2,2) println(x+y) }
这里演示的是 A类的 x+y 操作符重载。细节应该不用多说。
打印结果:
[i=3 , j=3]
再来一个较为复杂的栗子, 重载 a[i]
/** * 比如,B类中有一个成员,list,我想重载操作符,直接取到list中的元素 */ class B { val list: MutableList<Int> = mutableListOf(1, 2, 3, 4, 5, 6, 7, 8, 9) } //a[i] operator fun B.get(i: Int): Int { return list[i] } fun main() { val b = B() println("${b[2]}") }
打印结果:
3
最后一个栗子:a > b,对应函数为:a.compare(b)
/** * 学生class */ data class Student(val math: Int = 0, val chinese: Int = 0, val english: Int = 0) fun Student.toString():String{ return "[math:${math} chinese:${chinese} english:${english}]" } fun Student.totalScore(): Int { return math + chinese + english } /** * 比如,我们要直接比较两个学生的总分 */ operator fun Student.compareTo(s: Student): Int { return this.totalScore() - s.totalScore()//比较2个学生的总分 } fun main() { val s1 = Student(math = 50, chinese = 90, english = 100) val s2 = Student(math = 80, chinese = 70, english = 60) println("s1:${s1}") println("s2:${s2}") //比如存在这两个学生,我要知道他们的总分谁高谁低 println("学生s1,s2的总分:${if(s1 > s2) "s1比较高" else "s2比较高" }")
这篇关于Kotlin(3)-协程和操作符重载,金三银四Java高级工程师面试题整理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)