package com.example.kotlintest
import android.os.Build
import androidx.annotation.RequiresApi
import kotlinx.coroutines.*
import kotlin.reflect.KProperty
@RequiresApi(Build.VERSION_CODES.N)
suspend fun main() {
println("aaa")
var name = "alic"
var ss = "${name} is a boy"
println(ss)
var a: Int = 3
println("a=${a}")
var age = 10
var p = People(33, "alic")
println("${name} 年龄是 ${p.age}")
var list = listOf<String>("a", "b", "c", "d")
for (ss in list) {
println(ss)
}
var listmul = mutableListOf<String>("e", "f", "g")
listmul.add("h")
for (ss in listmul) {
println(ss)
}
println("sum=${sum(3, 7)}")
var ii = 20
if (ii == 10) {
println("ii=${ii}")
} else if (ii == 20) {
println("ii=${ii}")
}
println(large(3, 6))
println(getName("alic"))
getName1(3.0f)
//for循环
val num = 0..10
val num1 = 0 until 10
for (i in num) {
println("forEach 0..10 i= ${i}")
}
for (i in num1) {
println("forEach 0 unti 10 i= ${i}")
}
for (i in num1 step 2) {
println("forEach step i= ${i}")
}
for (i in 10 downTo 1) {
println("forEach downTo i= ${i}")
}
val student = Student(12, "alic")
student.eat()
student.studyChinese()
student.studyEnglish()
//数据类 data
var phone = Phone("dddd", 1233333)
println(phone)
//map
var map = HashMap<String, Int>()
map.put("alic", 11)
map.put("xiaoming", 33)
map.put("xiaomei", 55)
map["xiaoqiang"] = 74
println(" xiaoqiang的年龄是:${map["xiaoqiang"]}")
val mapof = mapOf("Apple" to 1, "Banana" to 2, "Orange" to 3, "Pear" to 4, "Grape" to 5)
println(SingleInstanch.getName("aaaaa"))
//Lambda 表达式的语法结构:
// {参数名1: 参数类型, 参数名2: 参数类型 -> 函数体}
val listof1 = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val lambda = { fruit: String -> fruit.length }
val maxLengthFruit = listof1?.let {
for (s in it) {
println(s)
}
}
val listmap = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
//map函数 统一对整个map进行处理
val newList = listmap.map { it.toUpperCase() }
for (fruit in newList) {
println(fruit)
}
println("-------------")
//filter 过滤
val newList1 = listmap.asSequence().filter { it.length <= 5 }
.map { it.toUpperCase() }
for (fruit in newList1) {
println(fruit)
}
//any all 返回一个boolean值
val anyResult = list.any { it.length <= 5 }
val allResult = list.all { it.length <= 5 }
println("anyResult is " + anyResult + ", allResult is " + allResult)
var thread = Thread {
println("Thread is running")
}.start()
doStudy(Student(333, "ddddd"))
// with函数 with函数接收两个参数:第一个参数可以是一个任意类型的对
//象,第二个参数是一个Lambda 表达式
// val result = with(obj) {
// 这里是obj的上下文
// "value" // with函数的返回值
// }
val builder = StringBuilder()
builder.append("Start eating fruits.\n")
for (fruit in list) {
builder.append(fruit).append("\n")
}
builder.append("Ate all fruits.")
val result = builder.toString()
println(result)
val result1 = with(StringBuilder()) {
append("Start eating fruits.\n")
for (fruit in list) {
append(fruit).append("\n")
}
append("Ate all fruits.")
toString()
}
println(result1)
//run函数
// 首先run函数通常不会直接调用,
// 而是要在某个对象的基础上调用;其次run函数只接收一个Lambda 参数,并且会在Lambda 表
// 达式中提供调用对象的上下文。其他方面和with函数是一样的,包括也会使用Lambda 表达式
// 中的最后一行代码作为返回值返回
val result3 = StringBuilder().run {
append("Start eating fruits.\n")
for (fruit in list) {
// 第 3 章 先从看得到的入手,探究 Activity 164
append(fruit).append("\n")
}
append("Ate all fruits.")
toString()
}
println(result3)
// apply函数 apply函数和run函数也是极其类似的,都要在某
//个对象上调用,并且只接收一个Lambda 参数,也会在Lambda 表达式中提供调用对象的上下
//文,但是apply函数无法指定返回值,而是会自动返回调用对象本身
val result4 = StringBuilder().apply {
append("Start eating fruits.\n")
for (fruit in list) {
append(fruit).append("\n")
}
append("Ate all fruits.")
}
println(result4.toString())
// apply 用于初始化对象或修改对象属性 是T的扩展函数 内部使用this ,返回值是本身
// also 将数据指派给接收对象的属性之前验证对象 是T的扩展函数,内部使用it,返回值是本身
// let 如果将对象进行空检查并访问或修改其属性 ,是T的扩展函数,内部使用it,最后一行是返回值
// run 如果计算某个值,或者限制多个本地变量的范围 是T的扩展函数 内部使用this ,最后一行是返回值
// with 需要传入对象 不是T的扩展函数,不能判空,最后一行是返回值
// infix自定义操作符
// 比如1 to 2 1 add 2
//单例
Util.doAction()
//静态方法
var com = ComUtil()
com.doAction1()
ComUtil.doAction2()
//对变量延迟初始化 声明为非空类型的属性在构造函数中初始化 不方便
// 延迟初始化使用的是lateinit关键字,它可以告诉Kotlin 编译器,我会在晚些时候对这个变量
// 进行初始化,这样就不用在一开始的时候将它赋值为null了。
lateinit var people: People
people = People(33, "alic")
println(people)
if (!::people.isInitialized) {
// adapter = MsgAdapter(msgList)
}
// 使用密封类优化代码 sealed修饰
println(getResultMsg(Success("yes")))
//扩展函数 fun ClassName.methodName(param1: Int, param2: Int): Int {
// return 0
//}
// 相比于定义一个普通的函数,定义扩展函数只需要在函数名的前面加上一个ClassName.的语
// 法结构,就表示将该函数添加到指定类当中了。
val count = "ABC123xyz!@#".lettersCount()
println("字符串中的字母个数是:${count}")
//高阶函数 一个函数接收另一个函数作为参数,或者返回值的类型是
//另一个函数,那么该函数就称为高阶函数。
//函数类型的 语法规则是
// (String, Int) -> Unit 箭头左边参数 右边返回值
// exaple()
//协程 1、GlobalScope
// 顶层协程 类似Thread不推荐
GlobalScope.launch {
println("codes run in coroutine scope")
}
Thread.sleep(1000)
//不推荐 可以保证在协程作用域内的所有代码
//和子协程没有全部执行完之前一直阻塞当前线程
// 会挂起外部线程,如果你恰好又在主线
// 程中当中调用它的话,那么就有可能会导致界面卡死的情况
//2、runBlocking
runBlocking {
println("codes run in coroutine scope")
delay(1500)
println("codes run in coroutine scope finished")
}
//创建多个协程
runBlocking {
launch {
println("launch1")
delay(1000)
println("launch1 finished")
}
launch {
println("launch2")
delay(1000)
println("launch2 finished")
}
}
// val start = System.currentTimeMillis()
// runBlocking {
// repeat(100000) {
// launch {
// println(".")
// }
// }
// }
// val end = System.currentTimeMillis()
// println(end - start)
//3、CoroutineScope
//使用协程进行主线程子线程切换
// CoroutineScope(Dispatchers.IO).launch {
// //io线程执行耗时操作
val image = getImage(imageId)
// launch(Dispatchers.Main) {
// //切换到主线程更新ui
avatarIv.setImageBitmap(image)
// }
// }
//Dispatchers.Main 代表主线程,只有在android项目中才生效,在纯kotlin项目中会报错
// CoroutineScope(Dispatchers.Main).launch { // 👈 在 UI 线程开始
// val image = withContext(Dispatchers.IO) { // 👈 切换到 IO 线程,并在执行完成后切回 UI 线程
getImage(imageId) // 👈 将会运行在 IO 线程
// }
avatarIv.setImageBitmap(image) // 👈 回到 UI 线程更新 UI
// }
// coroutineScope函数只会阻塞当前协程,既不影响其他协程,也不影响任何线程,因此是不
// 会造成任何性能上的问题的。而runBlocking函数由于会挂起外部线程,如果你恰好又在主线
// 程中当中调用它的话,那么就有可能会导致界面卡死的情况,所以不太推荐在实际项目中使
// 用。
//挂起函数 suspend
// 当协程域中的逻辑多 需要抽出来函数,但是函数里的逻辑还需要在协程域里才能生效,就需要将函数改为suspend 挂起
printDot()
printDotSuspend()
getImage(111)
//获取协程域里的执行结果 1、async 2、withContext
//async await 获取结果
//launch函数只能用于执行一段逻辑,却不能获取执行的结果,因为它的返回值 永远是一个Job对象
// async await 获取结果
runBlocking {
var result = async {
5 + 5
}.await()
println("async await result=${result}")
}
runBlocking {
val result = withContext(Dispatchers.Default) {
5 + 34
}
println(result)
}
//java 转成kotlin 1、复制java代码到kotlin文件,会提示是否转成kotlin 2、Code→Convert Java File to Kotlin File,
//kotlin不能自动转成java Kotlin 拥有许多Java 中并不存在的特性
//匿名内部类 object:xxxcallback
// xxx.setOnClickListener(object : xxxcalbbaic())
// 类委托的核心思想是将一个类的具体实现委托给另一个类去完成,而委托属性的核心思想是将
// 一个属性(字段)的具体实现委托给另一个类去完成。
//解构 将一个类对象中的参数拆解出来,成为一个一个单独的变量,对变量进行单独操作
// var teacher: Teacher = Teacher(33, "")
// val (age, name) = teacher
//1、类委托 操作对象自己不会去处理某段逻辑,而是会把工作委托给另外一个辅助对象去处理
// 2、属性委托
val pd = PropertyDelegation()
//读取属性,实际上是调用属性的委托对象的getter方法
println(pd.name)
//写入属性,实际上是调用属性的委托对象的setter方法
pd.name = "Kotlin"
println(pd.name)
//3、延迟属性 lazy()函数,该函数接受一个Lambda表达式作为参数,并返回一个Lazy对象。
//第一次程序会计算Lambda表达式并得到返回值,以后再调用,就不会计算lambda表达式,直接返回计算结果
//两次访问lazyProp属性
println(lazyProp)
println(lazyProp)
//第一次输出结果
//第一次访问时执行代码块
//Kotlin
//第二次输出结果
//Kotlin
//kotlin高阶函数的实现原理,每调一次Lambda表达式在底层被转换成了匿名类的实现方式,都会创建匿名内部类对象,造成额外的内存和性能开销 // 内联函数 inline 作用是在编译kotlin文件时直接将内联函数内联掉,这样就把内联函数执行过程放在调用此内联函数的位置,避免了java中多调用方法的操作,减少性能消耗
//kotlin编译器在编译的时候,将内联函数自动替换到调用它的地方,不存在运行时的开销了,避免了java的多调用方法的操作,减小内存开销
//noinline 对某个函数非内联
//内联函数和非内联函数的区别,内联函数lamdba表达式可以return进行函数返回,而非内联函数只能进行局部返回
//高阶函数转成java代码
// int res = number1AndNumber2(int num1, int num2,new Function(){
// @Override
// public Integer invoke(Integer n1,Integer n2){
// return n1+n2;
// }
// })
//Sequences 处理集合高效 减少循环次数
//map filter count会循环三次,asSequence 几个循环共用一个迭代器,一次循环就就可以完成
//map处理一个数据完成直接传递给filter继续处理
// list.asSequence()
// .map { it ++ }
// .filter { it % 2 == 0 }
// .count { it < 3 }
//协程是轻量级线程,线程是由系统调度的,线程切换或线程阻塞的开销比较大,协程依赖线程,协程挂起不需要阻塞线程,
//安全处理可空类型
a?.let { }
//如果a为空,不会报空指针,会返回null
//kotlin遍历的方式
//for foreach while do while
//协程Flow kotlin协程中使用挂起函数可是实现非阻塞地执行任务并将结果返回,但是只能返回单个计算结果,多个计算结果的话,就用到Flow
//@JVMOverLoads 修饰函数,自动暴漏多个重载方法
// @JvmOverloads
// fun f(a:Int,b:String,c:Double){}
// fun f(a:Int){}
// fun f(a:Int,b:String){}
// fun f(a:Int,b:String,c:Double){}
//List 只读,不能修改元素,继承EmptyList 没有add remove方法
// MultableList 可读可写 继承ArrayList
//data 数据类 自动实现equal hashCode toString
// == 对比内容 ===对比对象地址
//解构 将一个类的对象的参数拆分出来,成为一个个单独变量,使用这些单独变量进行操作
// var girl1: Student = Student(24,"嫚嫚")
// var (a,b,c,d) = girl1
// println("$a,$b,$c,$d")
// val const 都是不可变的,const必须在编译时知道 val也可以在运行时分配
// lateinit\lazy区别 lazy修饰val lateinit修饰var,不能保证不变性
//lateinit可以延迟初始化变量,声明时不用设置为可空
// 判断一个lateinit变量是否init this::name.isInitialized
list.forEach {
println("forEach:${it}")
}
//init代码块 在主构造方法执行完执行,想在构造方法里执行代码,就需要在init代码块里执行
//Conroutines launch async区别 async有返回值 配合await返回协程结果
//高阶函数 参数或者返回值是函数类型 如(num1:Int,num2:Int -> Int)
//高阶函数允许函数类型的参数决定函数的执行逻辑
var resultn: Int = number1AndNumber2(3, 5, ::minus)
println("number1AndNumber2:${resultn}")
println(example("alic",39, ::test))
var result8:Int = number1AndNumber2(44, 99) { n1, n2 ->
n1 * n2
}
println(result8)
var result9 =number1AndNumber2(44, 99) { n1, n2 ->
n1 / n2
}
println(result9)
var res=StringBuffer().build(){
append("Start English")
list.forEach {
append(it)
}
append("End English")
}
println(res)
}
//1、拓展函数build 参数是函数类型的
fun StringBuffer.build(block:StringBuffer.()->Unit):StringBuffer{
block()
return this
}
fun number1AndNumber2(num1: Int, num2: Int, operation: (Int, Int) -> Int): Int {
return operation(num1, num2)
}
fun plus(num1: Int, num2: Int): Int {
return num1 + num2
}
fun minus(num1: Int, num2: Int): Int {
return num1 - num2
}
fun example(name: String, age: Int, abc: (String, Int) -> String):String {
return abc(name, age)
}
fun test(name: String,age: Int):String{
return "${name} is ${age}"
}
val lazyProp: String by lazy {
println("第一次访问时执行代码块")
"Kotlin"
}
fun sum(a: Int, b: Int): Int {
return a + b
}
fun large(a: Int, b: Int): Boolean {
return a > b
}
fun large1(a: Int, b: Int) = if (a > b) true else false
fun getName(name: String) = when (name) {
"alic" -> 3
"lili" -> 4
"meimei" -> 5
else -> 0
}
fun getName1(name: Number) {
when (name) {
is Double -> {
println("我是Double:${name}")
}
is Int -> {
println("我是Int:${name}")
}
is Float -> {
println("我是Float:${name}")
}
}
}
fun getTextLength(text: String?) = text?.length ?: 0
fun doStudy(study: Study?) {
study?.let { stu ->
stu.studyChinese()
stu.studyEnglish()
}
}
object Util {
fun doAction() {
println("do action")
}
}
//只让某个方法变成静态
//companion object这个关键字实际上会
//在Util类的内部创建一个伴生类,而doAction2()方法就是定义在这个伴生类里面的实例方
//法。只是Kotlin 会保证Util类始终只会存在一个伴生类对象,因此调用Util.doAction2()方
//法实际上就是调用了Util类中伴生对象的doAction2()方法。
class ComUtil {
fun doAction1() {
println("do action1")
}
companion object {
fun doAction2() {
println("do action2")
}
}
}
//给单例类或companion object中的方
//法加上@JvmStatic注解,那么Kotlin 编译器就会将这些方法编译成真正的静态方法
class TurUtil {
fun doAction1() {
println("do action1")
}
companion object {
@JvmStatic
fun doAction2() {
println("do action2")
}
}
}
fun getResultMsg(result: Result) = when (result) {
is Success -> result.msg
is Failure -> result.error.message
else -> throw IllegalArgumentException()
}
interface Result
class Success(val msg: String) : Result
class Failure(val error: Exception) : Result
fun getResultMsg1(result: Result1) = when (result) {
is Success1 -> result.msg
is Failure1 -> result.error.message
}
sealed interface Result1
class Success1(val msg: String) : Result1
class Failure1(val error: Exception) : Result1
//统计字符串中字母的数量 拓展String类中的方法
fun String.lettersCount(): Int {
var count = 0
for (char in this) {
if (char.isLetter()) {
count++
}
}
return count
}
fun exaple(func: (String, Int) -> Unit) {
func("323fsfsf", 55)
}
//当协程域中的逻辑多 需要抽出来函数,但是函数里的逻辑还需要在协程域里才能生效,就需要将函数改为suspend 挂起
// suspend挂起 suspend关键字只能将一个函数声明成挂起函数
// launch函数要求必须在协程作用域当中才能调用。
suspend fun getImage(imageId: Int) = withContext(Dispatchers.IO) {
// IDE 报错 Suspend function'withContext' should be called only from a coroutine or another suspend funcion
}
suspend fun printDot() {
println("suspend 函数")
delay(1000)
//suspend只是关键字 声明函数可挂起 但是不能提供协程域
// launch{
//
// }
}
suspend fun printDotSuspend() = coroutineScope {
launch {
println("suspend 函数 增加协程域")
delay(1000)
}
}
class Delegate {
var propValue: Any? = null
operator fun getValue(myClass: MyClass, prop: KProperty<*>): Any? {
return propValue
}
operator fun setValue(myClass: MyClass, prop: KProperty<*>, value: Any?) {
propValue = value
}
}
class MyClass {}
// 类委托 操作对象自己不会去处理某段逻辑,而是会把工作委
//托给另外一个辅助对象去处理
class MySet<T>(val helperSet: HashSet<T>) : Set<T> {
override val size: Int
get() = helperSet.size
override fun contains(element: T) = helperSet.contains(element)
override fun containsAll(elements: Collection<T>) = helperSet.containsAll(elements)
override fun isEmpty() = helperSet.isEmpty()
override fun iterator() = helperSet.iterator()
}
class MySetBySomeClass<T>(val helperSet: HashSet<T>) : Set<T> by helperSet {
fun helloWorld() = println("Hello World")
override fun isEmpty() = false
}
//Kotlin属性委托,属性委托可以将多个类的类似属性统一交给委托对象集中实现,这样就可避免每个类都需要单独实现这些属性。
class PropertyDelegation {
//该属性的委托对象是MyDelegation
var name: String by MyDelegation()
}
class MyDelegation {
private var _backValue = "默认值"
operator fun getValue(thisRef: PropertyDelegation, property: KProperty<*>): String {
println("${thisRef}的${property.name}属性执行getter方法")
return _backValue
}
operator fun setValue(thisRef: PropertyDelegation, property: KProperty<*>, newValue: String) {
println("${thisRef}的${property.name}属性执行setter方法,传入参数值为${newValue}")
_backValue = newValue
}
}
Kotlin学习
android-李志强2024-02-24 7:07
相关推荐
拭心10 小时前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍带电的小王12 小时前
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型梦想平凡12 小时前
PHP 微信棋牌开发全解析:高级教程元争栈道13 小时前
webview和H5来实现的android短视频(短剧)音视频播放依赖控件阿甘知识库13 小时前
宝塔面板跨服务器数据同步教程:双机备份零停机元争栈道14 小时前
webview+H5来实现的android短视频(短剧)音视频播放依赖控件资源MuYe14 小时前
Android Hook - 动态加载so库居居飒15 小时前
Android学习(四)-Kotlin编程语言-for循环Henry_He18 小时前
桌面列表小部件不能点击的问题分析工程师老罗18 小时前
Android笔试面试题AI答之Android基础(1)