Kotlin 函数

本文介绍了Kotlin编程中的关键特性,包括Lambda表达式的使用,如参数标注、类型推断和单参数简化;标准函数如also、let和apply的上下文对象操作;扩展函数的概念和示例;高阶函数的定义和应用,如map、filter和collect;集合的函数式API,如maxBy、filter和slice;协程的异步处理能力以及lazy属性的延迟初始化。这些内容涵盖了Kotlin编程的核心概念和技术。
摘要由CSDN通过智能技术生成

1、Lambda

lambda 表达式总是括在花括号中, 完整语法形式的参数声明放在花括号内,并有可选的类型标注, 函数体跟在一个 -> 符号之后。如果推断出的该 lambda 的返回类型不是 Unit,那么该 lambda 主体中的最后一个(或可能是单个) 表达式会视为返回值。

//Lambda表达式的完整语法形式:
val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }
//函数的最后一个参数是函数,作为参数传入的lambda表达式可以放在圆括号外
val product = items.fold(1) { acc, e -> acc * e }
//若lambda表达式是调用时唯一的参数,则圆括号可以省略
val maxLengthFruit = list.maxBy { fruit : String -> fruit.length }
val maxLengthFruit = list.maxBy { fruit -> fruit.length }
//lambda表达式只有一个参数时可以用it隐式代替
val maxLengthFruit = list.maxBy { it.length }

2、标准函数

also、 let、 apply、 run、 with
上下文对象:
this:run、 with、 apply,通过关键字this引用上下文对象,在它们的 lambda 表达式中可以像在普通的类函数中一样访问上下文对象,大多数场景下当访问接收者对象时可以省略this。
it:let、also,将上下文对象作为lambda的参数,默认名称为it,当调用对象函数或属性时不能想this一样隐式访问对象。
返回值:
apply、 also返回上下文对象
let、 run、 with返回lambda表达式结果

3、扩展函数

在不修改某个类的源码的情况下,向该类添加新的函数为一个类添加一个新的函数或属性

//定义函数时在函数名前加要扩展的类名 ClassName.methodName()
fun String.lettersCount(): Int {
	var count = 0
	for(char in this){
		if(char.isLetter()) {
			count++
		}
	}
	return count
}

val num = "asfbHUHFhfHh@#".lettersCount()

4、高阶函数

函数类型:(String, Int)-> Unit
参数有“函数类型”或者返回值是“函数类型”的函数

fun example( func : ( String,Int) -> Unit ) {
	func(“hello”,1232) 
}

5、集合的函数式API

map():映射

val list = listOf("Apple","Banana","Orange","Pear","Grape","Watermelon")
val newlist = list.map { it.toUpperCase() }
for(fruit in newlist){
   println(fruit)//全大写
}

collect()
是流(Stream)对象的一个终端操作符,用于将流中的元素收集到一个集合或其他数据结构中

List<String> words = Arrays.asList("apple", "banana", "orange");
Set<String> collectedSet = words.stream()
                                .collect(Collectors.toSet());
Collectors.toSet()
Collectors.toList()

maxBy():找出长度最长的单词

val list = listOf("Apple","Banana","Orange","Pear","Grape","Watermelon")
var maxLengthFruit = list.maxBy { it.length }
println("max lenth fruit is "+maxLengthFruit)

filter():函数就是过滤集合中数据的,可以单独使用,也可以配合 map 函数使用

val list = listOf("Apple","Banana","Orange","Watermelon")
val newlist = list.filter { it.length <=5 }
    .map { it.toUpperCase() }
for(fruit in newlist){
    println(fruit)
}

slice():取集合中的一些元素创建新的集合

val numberList = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9)

val newNumberList1 = numberList.slice(IntRange(3, 6))
newNumberList1.forEach {
    print("$it ")	//打印结果:4 5 6 7
}
val newNumberList2 = numberList.slice(listOf(1, 3, 7))
newNumberList2.forEach {
    print("$it ")	//打印结果:2 4 8
}

take():从第一项开始取n个元素组成新的集合
takeLast():从最后一项开始取n个元素组成新的集合
takeWhile() :从第一项开始取满足条件的项组成新的集合
takeLastWhile():

val numberList = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9)
val newNumberList1 = numberList.take(3)
newNumberList1.forEach {
    print("$it ")	//打印结果:1 2 3
}

val strList = listOf("java", "javaScript", "kotlin",  "C++", "javaFx", "python", "Swift")
strList.takeWhile{ it.startsWith("java") }.forEach { print("$it  ") }
//java javaScript

drop(n) :从第一项删除n个元素
dropLast(n):从最后一项删除n个元素
dropWhile():从第一项删除满足条件的元素,直到遇到第一个不满足条件的为止
dropLastWhile():

val numberList = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9)
numberList.drop(5).forEach { print("$it   ") }//6 7 8 9

val strList = listOf("java", "javaScript", "kotlin",  "C++", "javaFx", "python", "Swift")
strList.dropWhile { it.startsWith("java") }.forEach { print("$it  ") }
//kotlin C++ javaFx python

distinct():去除集合中的重复元素
distinctBy():根据操作后的几个去除重复元素

val numberList = listOf(1, 1 , 2, 3, 4, 4, 6, 7, 8, 8)
numList.distinct()//1 2 3 4 6 7 8
numList.distinctBy {
	it + 1
}//2 3 4 5 7 8 9

any 函数用于判断集合中是否至少存在一个元素满足指定条件,返回True/False

val list = listOf("Apple", "Banana", "Orange", "Watermelon")
val anyResult = list.any { it.length <= 5 }

all 函数用于判断集合中是否所有元素满足指定条件,返回True/False

val list = listOf("Apple", "Banana", "Orange", "Watermelon")
val allResult = list.all { it.length <= 5 }

count():返回集合中的元素个数/返回集合中满足条件的元素个数

val strList = listOf("java", "javaScript", "kotlin",  "C++", "javaFx", "python", "Swift")
strList.count{ it.startsWith("java") }//3

None():如果集合为空返回True/如果集合中没有满足条件的元素返回True

val strList = listOf("java", "javaScript", "kotlin",  "C++", "javaFx", "python", "Swift")
strList.None{ it.startsWith("java") }//False

reduce与fold函数:将所提供的操作应用于集合元素并返回累积的结果,reduce的第一步则将第一个和第二个元素作为第一步的操作参数,fold提供一个初始值并将其作为第一步的累积值

val listFold = listOf("hello", "1", "2", "3", "4").fold("初始值") {
	acc, nextElement -> acc + nextElement 
}//初始值hello1234
val listReduce :String = listOf("hello", "1", "2", "3", "4").reduce {
	acc, str -> acc + str 
}//hello1234

plus():集合合并

val list1 = listOf("Apple", "Banana")
val list2 = listOf("Orange", "Watermelon")
val allResult = list1.plus{ list2 }//

6、java函数式api

先决条件:kotin代码中调研java方法,且该方法接收一个java单抽象方法接口参数(java单抽象方法接口指接口中只有一个待实现方法)

new Thread(new Runnable() {
    @Override
    public void run() {
        ...
    }
}).start();
Thread(object : Runnable {
    override fun run() {
        ...
    }
}).start()
Thread(Runnable {
	...
}).start()
Thread {
	...
}.start()

7、监听器

不通过新建接口类的方法实现,高阶函数

class Test(var listener:(value:Int) -> Unit) {
	var callBack: (result: String) -> Unit = {
    }
}
val test = Test {
	value -> ...//对value进行处理
	callBack = ...//对result值处理
}

8、liveData

一种观察者模式

val testLiveData = MutableLiveData<String>()
testLiveData.value = "..."

testLiveData.observe(this) {
	//对String进行处理
}
import com.jeremyliao.liveeventbus.LiveEventBus

const val EVENT_RESULT = "EVENT_RESULT"
LiveEventBus.get<Pair<Result?, String>>(EVENT_RESULT).post(data to request)//Result:自定义的数据结构类型
LiveEventBus.get<Pair<Result?, String>>(EVENT_RESULT).observe(this) {
	it.first
	it.second
}

9、协程

Kotlin 协程是一种用于简化异步编程的并发框架。它提供了顺序编写异步代码的能力,简化了线程切换和异常处理,并提供了作用域和取消的机制,使得异步编程更加容易、高效和可靠
runBlocking{…}:创建协程作用域。
MainScope:一个特殊的协程作用域,与主线程的生命周期相关。
viewModelScope.launch:和ViewModel组件生命周期相同
GlobalScope.launch:一个顶层的协程作用域对象,是一个单例对象,和整个应用程序的生命周期相同。
launch:协程启动函数
Dispatchers:协程中用于调度协程执行的调度器的工具类,调度器定义了协程在哪个线程或线程池上执行,Dispatchers.Default——默认调度器,CPU密集型任务;Dispatchers.IO——IO密集型任务;Dispatchers.Main——安卓主线程上执行任务。
withContext():用于切换协程上下文的函数,协程上下文包含了协程运行所需的执行环境,例如线程或调度器。
suspend:函数修饰符,用于标记挂起函数,挂起函数是可以在协程中使用的特殊函数,它可以暂停当前协程的执行,而不会阻塞线程。当一个协程调用一个挂起函数时,它会将控制权交给调用者,并在挂起函数执行完毕后恢复执行。

suspend fun FetchData(): String {
    delay(1000)
    return "Data from network"
}

suspend fun ProcessData(data: String): String {
    delay(2000)
    return "Processed data: $data"
}

fun main() {
    runBlocking {
        launch(Dispatchers.Default) {
            val fetchedData = FetchData()
            // 切换到 IO 调度器执行耗时的处理操作
            val processedData = withContext(Dispatchers.IO) {
                processData(fetchedData)
            }
            // 切换回默认调度器打印结果
            withContext(Dispatchers.Default) {
                println(processedData)
            }
        }
        println("Main thread continues")
    }
}

10、lazy

用来延迟初始化属性,直到我们第一次使用该属性时才进行实际的初始化操作。

val propertyName: Type by lazy {
    // 初始化代码块
    // 返回属性的值
}

by lazy是线程安全的适用于多线程,他的值只会被初始化一次,只适用于不可变属性(val),lazy是一个局部函数,它存储了一个线程安全的 Lazy 实例,负责保存属性的初始化状态和值,在需要时进行初始化。
lazy可带参数:

val propertyName: Type by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
    // 初始化代码块
    // 返回属性的值
}
LazyThreadSafetyMode.SYNCHRONIZED: 使用同步锁来保证线程安全。
LazyThreadSafetyMode.PUBLICATION: 在多线程环境中可能有多个线程同时执行初始化,但只有第一个执行完成的结果会被返回,其他线程会使用这个结果。
LazyThreadSafetyMode.NONE: 不保证线程安全性,适用于单线程环境。如果在多线程环境下使用此模式,可能会导致不确定的行为

initializer: () -> T: 这是 lazy 函数最常用的参数,用于指定属性的初始化操作。它是一个 lambda 表达式,返回属性的初始值。例如:
val propertyName: Type by lazy {
    // 初始化代码块
    // 返回属性的值
}

onUndecided: (T) -> Unit: 这个参数是一个 lambda 表达式,在属性的值尚未初始化时被调用。它接收一个参数,即属性的类型,并在属性的值尚未初始化时执行操作。例如:
val propertyName: Type by lazy(onUndecided = { uninitializedValue ->
    // 处理属性未初始化的情况
}) {
    // 初始化代码块
    // 返回属性的值
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值