数据类与单例类
数据类用data关键字修饰类,相当于JavaBean
data class Company(val name: String,val startTime:Int)
单例用object修饰类
object Singleton{
...
}
Lambda表达式与函数API
Lambda是一段可以作为参数的代码,代码最后一行自动作为返回值,形式:
{ 参数名1:参数类型,参数名2:参数类型 ->函数体 }
示例代码:
val list = mutableListOf("Apple","Banana","Pear","Grape")
val lambda = {fruit:String->fruit.length}
val maxLen = list.maxBy(lambda)
后两行代码可以表示为:
val maxLen=list.maxBy({fruit:String->fruit.length})
当Lambda是最后一个参数时,可以将表达式移到括号后面,即:
val maxLen=list.maxBy(){fruit:String->fruit.length}
Lambda是唯一参数时,可以去掉括号:
val maxLen=list.maxBy{fruit:String->fruit.length}
当Lambda表达式只有一个参数时,不用声明参数名,可以直接使用 it 代替,最终表示为:
val maxLen=list.maxBy{ it.length }
函数API之map
map可以将集合中的元素映射成另一个值,例如:
val list = mutableListOf("Apple","Banana","Pear","Grape")
val newList= list.map{ it.toUpperCase } //每个元素都改为大写
函数API之filter
filter用于过滤元素数据
val list = mutableListOf("Apple","Banana","Pear","Grape")
val newList= list.filter{ it.length < 5 }.map{ it.toUpperCase } //将元素长度小于5的元素改为大写
函数API之all与any
all表示所有元素满足条件,any表示至少一个元素满足条件
val list = mutableListOf("Apple","Banana","Pear","Grape")
val anyRes = list.any{ it.length < 5 } //判断list中是否存在长度小于5的元素
val allRes= list.all{ it.length < 5 } //判断list中是否所有元素长度都小于5
辅助工具 let
let是一个函数,形式:
obj.let { obj2 ->
// 逻辑
}
其中obj与obj2是同一对象。
示例:
fun study(stu:Student?){
stu?.doHomework();
}
用let表示:
fun study(stu:Student?){
stu?.let{ s->
s.doHomework();
}
}
//Lanbda只有一个参数,进一步简化
fun study(stu:Student?){
stu?.let{
it.doHomework();
}
}
标准函数with、run与apply
with用法
val res = with(obj){
// obj上下文
...//最后一行作为返回值
}
例子:
val res = with(StringBuilder()){
append("aaa")
append("bbb")
toString() //返回值
}
println(res) // 结果:aaabbb
run用法
val res = obj.run{
// obj上下文
...//最后一行作为返回值
}
例子:
val res = StringBuilder().run{
append("aaa")
append("bbb")
toString() //返回值
}
println(res) // 结果:aaabbb
apply用法
val res = obj.run{
// obj上下文
...//最后一行返回obj本身
}
例子:
val res = StringBuilder().apply{
append("aaa")
append("bbb") //返回值是 StringBuilder()对象
}
println(res.toString()) // 结果:aaabbb
静态方法
方式1:注解
class Util{
companion object{
@JvmStatic
fun doAction(){
println("doAction")
}
}
}
方式2:顶层方法(没有定义在任何类中的方法)
//创建Helper.kt文件,直接在里面写方法就是静态方法
fun action(){
println("action")
}
延迟初始化
private lateinit var adapter:MyAdapter
...
//判断是否初始化了
if(!::adapter.isInitialized){
//...
}
使用密封类优化代码
一般情况
interface Result
class Success(val msg:String):Result
class Fail(val error:String):Result
fun getResult(res:Result) = when(res){
is Success ->res.msg
is Fail -> res.error
else -> throw IllegalArgumentException() //必须添加
}
使用密封类
sealed class Result // interface 改为 sealed class
class Success(val msg:String):Result() //继承类后面加()
class Fail(val error:Exception):Result()
fun getResult(res:Result) = when(res){
is Success ->res.msg
is Fail -> res.error.message
//最后不用加else
}
1.密封类是一个可以继承的类
2.Kotlin会自动检查密封类有哪些子类,并强制要求对每个子类对应的条件处理
3.密封类及其子类只能定义在同一文件的顶层位置,不能嵌套在其他类中
扩展函数可以为现有类添加函数(添加API)
语法结构
fun ClassName.method(p1:Int,p2:Int):Int {
return 0
}
示例:自定义统计字符串长度
fun String.lettersLen():Int{
var count = 0
for (char in this){
if (char.isLetter()){
count++
}
}
return count
}
运算符重载
“+”运算符重载示例:
class Money(val value:Int){
//money + money
operator fun plus(money: Money):Money{
val sum = value + money.value
return Money(sum)
}
// money + v
operator fun plus(v: Int):Money{
val sum = value + v
return Money(sum)
}
}
调用
val money = Money(1)
val money2 = Money(2)
val money3 = money + money2
val money4 = money3 + 3
println(money4.value)
“*”运算符重载示例:
operator fun String.times(n:Int):String{
val sb = StringBuilder()
repeat(n){ //执行n次
sb.append(this) //this是String对象
}
return sb.toString()
}
表达式与实际函数对比
表达式 | 函数API |
---|---|
a + b | a.plus(b) |
a - b | a.minus(b) |
a / b | a.div(b) |
a % b | a.rem(b) |
a++ | a.inc() |
a - - | a.dec() |
+ a | a.unaryPlus |
- a | a.unaryMinus() |
! a | a.not() |
a - - | a.dec() |
a == b | a.equals(b) |
a < b、a > b、a >= b、a <= b | a.compareTo(b) |
a…b | a.rangeTo(b) |
a[b] | a.get(b) |
a[b] = c | a.set(b,c) |
a in b | b.contain(a) |
Kotlin学习笔记(一)