复习 Kotlin 从小白到大牛 第二版 笔记要点

4.2.2 常量和只读变量

常量和只读变量一旦初始化就不能再被修改。在kotlin中,声明常量是在标识符的前面加上val或const val 关键字。

1. val 声明的是运行时变量,在运行时进行初始化

2.const val 声明的是编译时常量,在编译时初始化

val 相当于 final

const val 相当于 public static final

5.4.1 可空类型概念

例子:

var n:Int = 10   n=null   编译错误

var n:Int?=10 n=null  可以

Kotlin 安全运算符

1.安全调用运算符?.

2.安全转换运算符 as?.

3.Elvis 运算符?:

  也叫 空值合并运算符  例子:

var a=divide(100,0)

int x=a?:0  

结果x=0

意思就是 假如a是空值,则让x=0  相当于给他一个默认值,空的就赋值0,避免了null 报错

4.非空断言 !!

6.2.5字符串比较

val s1="Hello"

val s2="HELLO"

s1.equals(s2,ignoreCase = true)//忽略大小写比较内容是否相等  结果为true

除了equals 之外,还有compareTo ,这个比较的是顺序,返回的是数字,

如果俩个字符串相等结果为0,前面的小就返回负数,大就返回正数

7.5其他运算符

冒号: 用于变量或者常量类型声明,以及声明继承父类和实现接口

小括号():起到改变表达式运算顺序的作用,他的优先级更高

中括号【】:索引访问运算符号

等号:赋值

可空符?标识一个可空类型

安全调用运算符?.   调用非空类型的函数或者属性

Elvis ?:     空值合并运算符

非空断言 !! 就是一定不会是空值

双冒号::  引用类,属性或函数

区间.. :表示一个范围区间

箭头-> 用来声明lambda 表达式

展开运算符*将数组传递给可变参数时使用

8.1分支结构

if else

when(){

x->{

}

}

do{

}while()

8.2.3 for语句

for( a int 0..9){

}

for(a int 0..list.size){}

for(item in list){}

//获取数组索引

for(i in list.indices){}

8.4 使用区间

for(x in 0..5) //定义区间包含0和5

for(x int 0 until 5) //定义半开区间包含0,不包含5

8.4.2 使用in 和!in 关键字

例子

var testScore=80   //设置一个测试分数
        var grade=when(testScore){
            in 90..100->"优秀"
            in 80 until 90->"良"
            in 60 until 80->"中"
            in 0 until 60->"差"
            else->"无"
        }

        if(testScore !in 60..100){
            println("不及格")
        }

        val strList= arrayOf("刘备","关羽","关羽")
        var name="赵云"
        if(name !in strList){
            println(name+"没结义")
        }

函数

fun 函数名(参数列表) : 返回值类型{

        函数体

        return 返回值

}

9.3.1使用命名参数调用函数

xxx(100,100)//没有采用

xxx(width=100,height=100)//采用命名函数

xxx(100,height=100)//采用

这个操作,之前的java使用参数提示的,命名函数可能有其他操作吧

9.3.2参数默认值

 9.3.3可变参数

 这里可以和扩展运算符*结合

9.5 局部函数

9.6匿名函数

 fun nimingTEST(a:Int,b:Int):String{
        val xxx=if(a==b)
            fun (x1 : Int, x2:Int):String{return (x1+x2).toString() }
        else
            fun (x1 : Int, x2:Int):String{return (x1-x2).toString() }
        return  xxx(a,b)
    }

感觉这个不如一条一条列出来清晰

10.4.1 Bean

 

 10.4.3延迟初始化属性

lateinit 字面意思延迟初始化,用的时候才会实例化,实例化是占内存,这个可以避免内存消耗吧

lateinit 关键字放在var之前,不能是可空类型

10.4.6可观察属性

 这里做了一个点击查看的操作,是可以监听到的,

10.5.1扩展函数


    //基本数据类型扩展
    fun Double.interestBy(interestRate: Double): Double {
        return this * interestRate
    }

    //自定义账户类
    class Account {
        var amount: Double = 0.0 //账户金额
        var owner: String = ""  //账户名
    }

    //账户类函数扩展
    fun Account.interestBy(interestRate: Double): Double {
        return this.amount * interestRate
    }

 Double 类型可以引用

 看起来很方便

这个看起来只能在当前类中使用

肯定可以写全局的

写一个文件,注意是文件不是类

 这样直接在其他地方可以用了,需要注意是在同一个包里

10.6构造函数

 默认是自带无参数构造


10.8.1声明数据类

创建一个类,区分了是数据类还是工具类还是其他类

数据类关键词data

添加一个data关键字后变成了数据类,底层数据类

底层的三个方法

hash()  toString equals 另外增加了一个copy的方法

data 修饰的类 参数有要求,必须要有var/val修饰

 

打印出来是2,也就是 修改了其中一个值其他都是之前的

10.10嵌套类

 无法访问外部类成员变量

加一个内部类关键字就可以了

 10.11.1对象表达式

Object关键字

接口回调

 

10.11.3 伴生对象

Kotlin 没有 java中的Static 所以

伴生类不能访问外部类的成员属性啥的,这个交互起来,还是以外部类为主

11.继承与多态

关键字open,Kotlin 默认是 final修饰的类和属性只有加上open才能被继承

 都一样,哪个代码少用哪个

11.4.1 is as

is 相当于 instanceof    as 相当于强类型转换

13.2.4 函数作为参数调用

费劲巴拉的你直接宽*高不就得了。

13.3Lambda 表达式


使用案例2

 简便了为啥我感觉花里胡哨的没有java通俗易懂


 简化之后Int直接省略了

省略写法

 没啥意思啊~


13.3.4 return

 return@foreach可以跳出本次循环,return 和 break 会跳出整个循环

 这种写法就可以用continue


13.4.闭包与捕获变量

这个有点绕

 


13.5内联函数

关键字inline

13.5.2Let函数

let的特点 1  最后一行是赋值

let特点2非空检查

在koltin中防止引用null对象,所有的对象都可以调用let方法,为空时不执行,不为空时执行

 a是自己取的名字,可以使用默认的it

let特点3 直接读取调用链结果

例子

这里拿到的是他们的长度,但是我想要字符串本身

 直接拿到数据

map是转换的意思

run

with

和run类似,但是他没有返回值

 apply

        

also


 泛型

假设要做一个比较的方法

这里只能比较int 参数

在方法名之前加上<T>就行了,一般都是TEKU

如果是多类型的<T,U>,中间用逗号隔开

14.1.3泛型约束

假如只想比较数字方向的类型,可以大概给个Number,他的子类有Int Double

 也可以写成

Comparable<T>包括了很多可以比较的类型,前后的参数一定要一个类型的

14.1.4可空类型参数

假如参数是空的,我们需要防止

可空

 不可空

3大基础函数

filter

过滤

map

转换

reduce

聚合

 聚合函数

阶乘

     // n个元素
        val intArray = IntArray(2) {
            it + 1
        }
        val reduce = intArray.reduce { acc, i ->
            acc * i
        }
        println(reduce)

从1开始到n的阶乘


 结果是从0到999


19协程

在执行阻塞任务时.会将这种任务放到子线程中,执行完成再回调(callback)主线程,更新UI等操作,这就是异步编程。协程底层库也是异步处理阻塞任务,但是这些复杂的操作被底层库封装起来。协程代码的程序流是顺序的,不再需要一堆的回调函数,就像同步代码一样,也便于理解,调试和开发

线程是抢占式的,线程调度是操作系统级的,而协程是协作式的,协程调度是用户级的,协程是用户空间线程,与操作系统无关,所以需要用户自己去做调度

19.2创建协程


 launch 函数的返回值是一个Job对象,Job是协程要执行的任务,可以将Job对象看做协程本身,所有对协程的操作都是通过Job对象完成的,协程的状态和生命周期都是通过Job反应出来的

Job对象的常用属性和函数

isActive 判断Job是否处于活动状态

isCompleted判断Job是否处于完成状态

isCanceled判断Job是否处于取消状态

start 开始Job

cancel取消Job

join 当前协程处于等待状态,知道Job完成,join是一个挂起函数,只能在协程体中或其他的挂起函数中调用

launch 和 runBlock 是相反的,runBlock 会阻塞线程

 从这里可以看出通过.launch开启一个协程会被先挂起,同级别的代码会先运行,


 

 

suspend是一个协程的关键字,被他修饰的函数就会挂起,例如这个delay(),他只能在协程方法体内运行,当遇到了suspend函数的时候,当前的协程就会主动逃离当前的线程去别的地方执行任务,当函数比如delay 500  执行完了,他就会回来线程继续执行

suspend就是让协程该走就走,执行完在回来,给主线程或者说同级别的代码块更好的运行

这里的运行顺序换成runBlock

 和上面相反程序会等runblock 执行完再执行下面

由于这种操作有可能阻塞主线程,所以很少有


简单实用的场景

butStart.setOnClickListener(View.OnClickListener {
            val coroutineScope = CoroutineScope(Dispatchers.Main)
            coroutineScope.launch {
                withContext(Dispatchers.IO) {
                    Thread.sleep(5000)
                    a = 20
                }
                text.text = ""+a
            }
        })
可以通过withContext 把它切换到子线程,

 以后用它替换java的AsycnTask吧,至于其他方法太烦了


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值