kotlin 小笔记

715 阅读7分钟

用kotlin写项目有一段时间了,从没进行过记录总结,从今天开始吧。

一、kotlin的优点 1.简洁(数据类扩展方法区间) 2.空值安全(针对空值处理的运算符)

private var data: Bean? = null
//可空类型 可以赋值为null
text = data?.info?.name?:""
//空安全调用符:?   Elvis操作符  ?:
//关闭空检查  a!! 不建议使用

声明数据是可空类型 然后再下边进使用的时候进行处理,如果最后为null返回“” 3.100%兼容java scala 4.函数式编程JDK1.8lambda表达式 5.协程(thread) 6.DSL(领域特定语言)

官方文档: kotlinlang.org/docs/refere… Kotlin源码: github.com/JetBrains/k… Kotlin官方博客: blog.jetbrains.com/kotlin

开发工具 Intellij IDEA | android studio

二、基本数据类型

数据类型 占用字节 取值范围
Boolean 1byte true or false
Byte 1byte=8bit -128~127
Char 2byte
Short 2byte=16bit -32768~32767
Int 4byte -2147483648~2147483647
Float 4byte 精确到小数点后6位
Long 8byte -9223372036854775807~9223372036854775807
Double 8byte 精确到小数点后15-16位

基本和java一样只是首字母都是大写了

三、数据处理 var 是可变变量 val 是不可变变量 1.字符串对比 == 相当于java的 equals()
=== 相当于java的 == 比较地址值

二元元组 val pair = "张三" to 20 三元元祖 val triple = Triple<String,Int,String>("李四",20,"15456678")

四、函数种类

//无参无返回值
fun sayHello(){//返回值
    println("hello")
}
//有参无返回值
fun sayHello(name:String){
    println("hello "+name)
}
//有参有返回值
fun getLength(name:String):Int{
    return name.length
}
//无参有返回值
fun get():String{
    return "hello"
}

1.循环

val str  = "abcd"
    /*---------------------------- for循环 ----------------------------*/
    for (a in str) {
       println(a)
    }
    for ((index,c) in str.withIndex()) {
        println("index=$index c=$c")
   }

    /*---------------------------- foreach ----------------------------*/
    str.forEach {
       println(it)
   }  
    str.forEachIndexed { index, c ->
        println("index=$index c=$c")
    }

函数表达式

fun add(a:Int,b:Int) =  a+b
val padd:(Int,Int)->Int = {a,b->a+b}//匿名函数
fun add(vararg a:Int) // vararg 数量可变参数

递归

/**
 * 求n的阶乘
 */
fun fact(n:Int):Int{
        if(n==1){
            return 1
        }else{
            return n* fact(n-1)
        }
}
/**
 * 求第n个斐波那契数列
 */
fun fibonacci(n:Int):Int{
    if(n==1||n==2){
        return 1
    }else{
        return fibonacci(n-2)+ fibonacci(n-1)
    }
}

迭代

* 递归:优点:逻辑比较简单  容易实现  缺点:容易栈内存溢出(内存开销比较大)
 * 迭代:优点:内存开销小 缺点:抽象出数学模型
/**
 * 求1到n的和  通过迭代的方式求和
 */
fun sum1(n: Int): Int {//kotlin里面参数是固定  不能修改
    var result = 0
    var copyN = n
    while (copyN > 0) {
        result += copyN
        copyN--
    }
    return result
}

对象属性访问器

fun main(args: Array<String>) {
    val person = Person()
    person.age = 90
    person.age
    person.age = 40
    println(person.age)
}
//直接访问还是get和set方法
class Person{
    var name  = "张飒"//只能访问不能修改
    private set//私有了set方法

    var age = 20//age超过150岁不能设置了
    set(value) {
            if(value<150){
//            this.age = value//age的set方法
                field = value//age的set方法
            }
    }
}

继承 父类用open修饰

多态

/**
 * ClassName:`14.多态`
 * 多态特点:通过父类接收  执行的是子类的方法
 */
fun main(args: Array<String>) {
    //创建狗和猫的对象
    val dog: Animal = Dog()
    val cat = Cat()
    dog.call()
//    cat.call()
}
//动物
abstract class Animal {
    var color: String = ""
    //行为
    open fun call() {
        println("动物叫")
    }
}
//狗
class Dog : Animal() {
    override fun call() {
        println("狗汪汪叫")
    }
}
//猫
class Cat : Animal() {
    override fun call() {
        println("猫喵喵叫")
    }
}

类委托

fun main(args: Array<String>) {
    val smallHeadFather = SmallHeadFather()
    //小头爸爸洗碗
    smallHeadFather.wash()
}
//洗碗能力
interface WashPower{
    //洗碗行为
    fun wash()
}
//大头儿子
class BigHeadSon:WashPower{
    override fun wash() {
        println("大头儿子开始洗碗了")
    }
}

//小头爸爸 将洗碗的能力委托给大头儿子
class SmallHeadFather:WashPower by BigHeadSon()
//或者
class SmallHeadFather(var washPower: WashPower):WashPower by washPower

单例模式 object单例 所有的字段都是static静态 方法不是 object使用条件:字段不多的时候

静态 companion object { //静态的name var name = "张三" }

枚举 enum class WEEK{//数据 星期一,星期二,星期三,星期四,星期五,星期六,星期日 } enum class COLOR(var r:Int,var g:Int,var b:Int){ RED(255,0,0),BLUE(0,0,255),GREEN(0,255,0) }

数据类型

data class News(var title:String,var desc:String,var imgPath:String,var content:String)
 val news = News("标题","简介","路径","内容")
    news.title
    news.desc

    news.component1()//第一个元素
    news.component2()//第二个元素

    //解构
    val (title,desc,imgPath,content) = News("标题","简介","路径","内容")

密封类?

五、高阶函数

//第三个参数是函数类型 说明kotlin里面的函数可以传递函数参数  如果函数里面传递函数参数的话 就称为高阶函数
fun cacl(a:Int,b:Int,block:(Int,Int)->Int):Int{
    //使用工具
    val result = block(a,b)
//    val result = block.invoke(a,b)
    return result
}

lambda表达式 闭包:函数不保存状态,闭包可让函数携带状态(函数返回内部函数,引用了外部变量,内部函数是闭包) Lambda就是匿名函数 调用全面的高阶函数 参数里有函数就是高阶函数

fun main(args: Array<String>) {
    var a = 10
    var b = 20
    var sum = 0//a+b
    var result = 0//a-b

    //只能我用这个工具  不能让其他人用
    //函数的参数定义出来之后 可以自动推断出类型  返回值不需要写 推断出当前的返回值类型
    //匿名函数 lambda表达式
    sum = cacl(a,b,{m:Int,n:Int->
        m+n  //return m+n
    })//第三个参数应该是函数的引用  比如 ::add 括号可以前移
    result = cacl(a,b,{m,n->
        m-n
    })
    println(sum)
    println(result)
}

fun cacl(m:Int,n:Int,block:(Int,Int)->Int):Int{
    val result = block(m,n)
    return result
}
invoke 和 () 都可调用lambda表达式
返回值不用return 是最后一行的返回值
只有一个参数 可以使用it

集合

过滤
传入一个函数,返回新的集合
list.filter{  }
传入一个函数,返回一个值
list.find{  }
传入目标集合 将符合条件的对象放入
MutableListOf<String>()
list.filterTo(MutableListOf,{})
传入角标过滤
list.filterindex(index,s{})

排序
list.sorted 正序
list.sortedDescending 倒序
list.sortedBy() 按照条件排序 传入的参数实现compter

分组
list.groupBy() 返回map 

最值
list.max()
list.maxBy()

去重复
list.toSet() 
list.distinct()
list.distinctBy()

拆分
list.partition{} 返回的是二元元祖
重新组合
list.map
集合相加
list.sumBy

大接收者函数字面值 T.()->Unit lambda 相当于定义在T里面的函数 访问对象里面的字段或方法 调用的时候两种1.Data().block() 2. block(Data())

四大函数 /** * 任意类型都有apply函数扩展 * apply参数是一个函数 T.() -> Unit 带接收者的函数字面值 * lambda表达式里this代表调用的对象 * 在lambda表达式里可以访问对象的方法 * apply函数返回值就是调用者本身 */ list?.apply{ 可指直接操作list 比如add 返回值是调用者本身 }

/** * 任意对象都有let扩展函数 * let函数参数也是一个函数 * 函数参数它的参数是调用者本身 * let函数返回值是函数参数的返回值 就是lambda表达式的返回值 */ list?.let{ 返回值是函数参数的返回值 就是lambda表达式的返回值 }

/** * with是独立的函数 可以在任意地方调用 * with函数需要接收两个参数 * 第一个参数可以接收任意类型 * 第二个参数是函数参数,并且这个函数参数是带接收者的函数字面值 接收者就是第一个参数 * with函数返回值是第二个函数参数的返回值 * 相当于apply和let的结合 */ with(list){ 独立函数 可在任意地方调用 }

/** * 任意类型都有run扩展函数 * run函数参数是待接收者的函数 接收者是调用者本身 * run函数返回值就是函数参数的返回值 */ list.run { }

接口回调 A 传 具有某种能力的接口 到B ,B将 其中的值或对象 通过接口中的方法传给A,A中的对象实现了这个接口 在它重写的方法中拿到B的值或者对象 函数回调 传了一个Lambda表达式也就是匿名函数{}

六、Gradle(需看视频)

七、协程(需看视频)