用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(需看视频)
七、协程(需看视频)