一,高阶函数
1,基本概念:将函数作为参数或返回一个函数,称为高阶函数,常用的高阶函数如下。
①,forEach函数,用于遍历集合
fun main(args: Array<String>): Unit {
val list : List<String> = listOf(
"red",
"orange",
"yellow",
"gree",
"blue"
)
//这里的两个冒号是引用函数的意思
list.forEach(::println)
}
②,map函数,集合映射
fun main(args: Array<String>): Unit {
val list : List<String> = listOf(
"red",
"orange",
"yellow",
"gree",
"blue"
)
var newMap=list.map { it+",hello" }
newMap.forEach(::println)
}
③,flatMap函数,把集合的集合扁平化成集合
fun main(args: Array<String>): Unit {
val list = listOf(
1..5,
3..15,
8..20
)
val newList = list.flatMap {
it
}
newList.forEach(::println)
}
④,reduce函数,用于求和
//示例1 求1到5的和
fun main(args: Array<String>): Unit {
val list = listOf(1, 2, 3, 4, 5)
var sum = list.reduce { acc, i -> acc + i }
println(sum)
}
//示例2
fun main(args: Array<String>): Unit {
(1..8).map(::factorial).forEach(::println)
}
//求n的阶乘:n!=1×2×3×...×n
fun factorial(n: Int): Int {
if (n == 0) {
return 1
} else {
return (1..n).reduce { acc, i -> acc * i }
}
}
⑤,filter数据过滤
//还是示例2的代码,要求只保留奇数,过滤掉其他
println((0..8).map(::factorial).filter { it%2==1 })
二,协程
1,基本概念:协作程序,解决异步问题。
2,协程与线程的区别:协程是通过编译技术实现(不需要虚拟机VM/操作系统OS的支持),通过插入相关代码来生效!与之相反,线程/进程是需要虚拟机VM/操作系统OS的支持,通过调度CPU执行生效!
3,想要使用协程首先需要加入两个库
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
4,开启一个协程
fun main(){
GlobalScope.launch {
println("这是一个协程")
}
Thread.sleep(1000)
}
使用 GlobalScope可以简单的开启一个协程,为什么要加一个 Thread.sleep(1000),因为如果不加这段代码不会有输出。这里创建的是GlobalScope.launch协程,是一个顶层协程,这种协程当应用程序运行结束时也会跟着一起结束。
5,再次使用协程
fun main(){
runBlocking {
println("开始")
delay(1500)
println("结束")
}
}
协程的另一种使用,这种的协程runBlocking 中的代码会执行完成。
6,协程效率
fun main(){
val start=System.currentTimeMillis()
runBlocking {
repeat(100000){
launch {
println("--")
}
}
}
val end=System.currentTimeMillis()
println(end-start)
}
这段代码执行了10万个携程,用时624毫秒,效率就是高呀,如果是线程早就崩溃了。
三,扩展函数
1,let 函数
在函数块内可以通过 it 指代该对象。返回值为函数块的最后一行或指定return表达式。
//使用前
mVideoPlayer?.setVideoView(activity.course_video_view)
mVideoPlayer?.setControllerView(activity.course_video_controller_view)
mVideoPlayer?.setCurtainView(activity.course_video_curtain_view)
//使用后
mVideoPlayer?.let {
it.setVideoView(activity.course_video_view)
it.setControllerView(activity.course_video_controller_view)
it.setCurtainView(activity.course_video_curtain_view)
}
2,with 函数
和let使用方式略有不同,因为它不是以扩展的形式存在的。它是将某对象作为函数的参数,在函数块内可以通过 this 指代该对象。返回值为函数块的最后一行或指定return表达式
适用于调用同一个类的多个方法时,可以省去类名重复,直接调用类的方法即可,经常用于Android中RecyclerView中onBinderViewHolder中,数据model的属性映射到UI上。
//使用前
override fun onBindViewHolder(holder: ViewHolder, position: Int){
val item = getItem(position)?: return
holder.nameView.text = "姓名:${item.name}"
holder.ageView.text = "年龄:${item.age}"
}
//使用后
override fun onBindViewHolder(holder: ViewHolder, position: Int){
val item = getItem(position)?: return
with(item){
holder.nameView.text = "姓名:$name"
holder.ageView.text = "年龄:$age"
}
}
3,run 函数
实际上可以说是let和with两个函数的结合体,run函数只接收一个lambda函数为参数,以闭包形式返回,返回值为最后一行的值或者指定的return的表达式。
//使用前
override fun onBindViewHolder(holder: ViewHolder, position: Int){
val item = getItem(position)?: return
holder.nameView.text = "姓名:${item.name}"
holder.ageView.text = "年龄:${item.age}"
}
//使用后
override fun onBindViewHolder(holder: ViewHolder, position: Int){
val item = getItem(position)?: return
item?.run {
holder.nameView.text = "姓名:$name"
holder.ageView.text = "年龄:$age"
}
}
4,apply函数
apply函数和run函数也是极其类似的,都是在某个对象上调用。
//使用前
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("param1", "data1")
intent.putExtra("param2", "data2")
startActivity(intent)
//使用后
val intent1 = Intent(this, SecondActivity::class.java).apply {
putExtra("param1", "data1")
putExtra("param2", "data2")
}
startActivity(intent1)
上一篇:kotlin基础篇