kotlin与java的区别
(1)java的函数先有输出,再有输入
(2)kotlin的函数先有输入,再有输出
1、kotlin的空检测机制
var name:String ?= null
(1) name?.length name如果真的是null后面的不执行,就不会引发空指针异常
(2) name!!.length 无论name是否为null,后面的都会执行,和java一样
(3)if(name!=null) name.length 同java
2、val 与 var 类型推断
(1)val 可读不可改 ,不能再重新赋值
val name:String ="zhangsan"
println("name:$name")
(2)var 可读可改
var sex:Char = 'M'
sex= 'A'
println("sex:$sex")
(3)val与var使用场景
尽量使用val,如果后续此变量需要更改,就使用var
(4)类型推断,推断出name为字符串类型
val name="dany"
3、函数
//隐士的Unit等价于java中的void
fun save():Unit{
}
//等同于
fun save(){
}
//有参数的,number1和number2为形参
fun add(number1:Int,number2:Int):Int{
return number1+number2
}
//一行简写方式,等用于如上
fun add(number1:Int,number2:Int):Int = number1+number2
//类型推导,返回值为int
fun method()= 100
4、内置数据类型
String 字符串
Char 单字符
Boolean true/false
Int 整型
Double 小数
List集合
Set 无重复的元素集合
Map 键值对的集合
Int ------->转换成java的int
Float ---------------->转换成java的float
5、Kotlin的编译时常量
编译时常量只能是常用的基本数据类型:String , Double , Int , Float , Long ,Short , Byte , Char , Boolean
const val PI = 3.1415926 //定义编译时常量
注意:修饰符const 不适用于局部变量,只能在函数之外定义,就可以在编译期间初始化了
val info = "info" //只读类型的变量
6、返回值类型
Unit 相当于java中的void
Any 相当于java中的Object
Int Double 引用类型 = 反编译后= KT int double
Double? =反编译后 = Double
函数声明
java: public void method1()
kotlin: var method:() -> Unit
函数声明实现结合
java: public void method1(){}
kotlin: var method={ printlin("aaaaaaaaaa")}
7、kotlin的range表达式
val score = 98
fun getScore() {
if (score in 0..59) {
LogUtil.d("不及格")
} else if (score in 60..79) {
LogUtil.d("中等")
} else if (score in 80..100) {
LogUtil.d("优秀")
} else if (score !in 0..100) {
LogUtil.d("不在0-100范围内")
}
}
8、kotlin的when表达式
val week = 6
val content = when (week) {
1 -> "星期一"
2 -> "星期二"
3 -> "星期三"
4 -> "星期四"
5 -> "星期五"
6 -> "星期六"
7 -> "星期日"
else -> {
LogUtil.d("其他")
}
}
9、kotlin的String模板
(1)$变量名 空格(后面不接字符串)
(2)${变量名}(后面可接字符串)
val content = "aaa"
val time = 6;
LogUtil.d("打印:${content}哈哈,去了$time 次")
//KT的if是表达式,所以更灵活 java的if是语句还有局限性
var isLogin = true
LogUtil.d("${if (isLogin) "登录成功了" else "登录失败了" }")
10、kotlin函数中的默认值
fun getDefaultData(name:String="lisi",age:Int=18){
LogUtil.d("姓名:$name,年龄:$age")
}
调用:可以赋值也可以不赋值
getDefaultData()
11、kotlin的具名函数参数
fun getStuInfo(name: String,age: Int,sex:String,password:String,info:String){
LogUtil.d("姓名:$name,年龄:$age")
}
调用:
getStuInfo(age = 10,password = "123456",sex = "男",name = "哈哈",info = "111")
12、kotlin的Nothing类型特点
fun show(score: Int) {
when (score) {
in 0..59 -> LogUtil.d("不及格")
in 60..79 -> LogUtil.d("及格")
in 80..100 -> LogUtil.d("优秀")
-1 -> TODO("没有这种分数") //结束当前程序
}
}
13、kotlin的反引号中函数名特点 esc键下面的键
is/in在kt里面就是关键字,怎么办呢,使用反引号
MainActivity.`in()`
14、kotlin的匿名函数
val num = "marry".count() //5
val count = "marry".count{
it.equal("r")
}
//有几个r字符串,2个
15、Kotlin的函数类型&隐式返回学习
// 第一步:函数输入输出的声明
val methodAction : () -> String
// 第二步:对上面函数的实现
methodAction = {
val inputValue = 999999
"$inputValue marry" // == 背后隐式 return "$inputValue marry";
// 匿名函数不要写return,最后一行就是返回值
}
// 第三步:调用此函数
println(methodAction())
16、Kotlin的函数参数
// 第一步:函数输入输出的声明 第二步:对声明函数的实现
val methodAction : (Int, Int, Int) -> String = { number1, number2, number3 ->
val inputValue = 999999
"$inputValue hh 参数一:$number1, 参数二:$number2, 参数三:$number3"
}
// 第三步:调用此函数
println(methodAction(1, 2, 3))
17、Kotlin的it关键字特点
//一个参数时,隐式参数为it
val methodAction2 : (String) -> String = { "$it hh" }
println(methodAction2("DDD"))
18、Kotlin的lambda学习
// 匿名函数 == lambda表达式
val addResultMethod = { number1 : Int, number2: Int ->
"两数相加的结果是:${number1 + number2}"
} // addResultMethod 函数: (Int, Int) -> String
println(addResultMethod(1, 1))
// 匿名函数 入参 Int, 返回 Any类型
// lambda表达式的参数 Int, lambda表达式的结果Any类型
val weekResultMethod = { number: Int ->
when(number) {
1 -> "星期1"
2 -> "星期2"
3 -> "星期3"
4 -> "星期4"
5 -> "星期5"
else -> -1
}
} // weekResultMethod 函数: (Int) -> Any
println(weekResultMethod(2))
// 匿名函数 属于 lambda
19、在函数中定义参数是函数的函数 及函数内联
fun main() {
loginAPI("hh", "123456") { msg: String, code: Int ->
println("最终登录的情况如下: msg:$msg, code:$code")
}
}
// 模拟:数据库SQLServer
const val USER_NAME_SAVE_DB = "hh"
const val USER_PWD_SAVE_DB = "123456"
// 此函数有使用lambda作为参数,就需要声明成内联
// 如果此函数,不使用内联,在调用端,会生成多个对象来完成lambda的调用(会造成性能损耗)
// 如果此函数,使用内联,相当于 C++ #define 宏定义 宏替换,会把代码替换到调用处,调用处 没有任何函数开辟 对象开辟 的损耗
// 小结:如果函数参数有lambda,尽量使用 inline关键字,这样内部会做优化,减少 函数开辟 对象开辟 的损耗
// 登录API 模仿 前端
//responseResult: (String, Int) -> Unit相当于java中的自定义接口
public inline fun loginAPI(username: String, userpwd: String, responseResult: (String, Int) -> Unit) {
if (username == null || userpwd == null) {
TODO("用户名或密码为null") // 出现问题,终止程序
}
// 做很多的校验 前端校验
if (username.length > 3 && userpwd.length > 3) {
if (wbeServiceLoginAPI(username, userpwd)) {
// 登录成功
// 做很多的事情 校验成功信息等
// ...
responseResult("login success", 200)
} else {
// 登录失败
// 做很多的事情 登录失败的逻辑处理
// ...
responseResult("login error", 444)
}
} else {
TODO("用户名和密码不合格") // 出现问题,终止程序
}
}
// 此函数没有使用lambda作为参数,就不需要声明成内联
// 登录的API暴露者 服务器
private fun wbeServiceLoginAPI(name: String, pwd: String) : Boolean {
// kt的if是表达式(很灵活) java的if是语句(有局限性)
// 做很多的事情 登录逻辑处理
// ...
return if (name == USER_NAME_SAVE_DB && pwd == USER_PWD_SAVE_DB) true else false
}
20、Kotlin的函数引用学习
::函数名
fun main() {
// 函数引用
// lambda属于函数类型的对象,需要把methodResponseResult普通函数变成 函数类型的对象(函数引用)
// login("hh", "123456", ::methodResponseResult)
val obj = ::methodResponseResult
val obj2 = obj
val obj3 = obj2
login("hh", "123456", obj3)
}
fun methodResponseResult(msg: String, code: Int) {
println("最终登录的成果是:msg:$msg, code:$code")
}
// 模拟:数据库SQLServer
const val USER_NAME_SAVE_DB4 = "hh"
const val USER_PWD_SAVE_DB4= "123456"
inline fun login(name: String, pwd: String, responseResult: (String, Int) -> Unit) {
if (USER_NAME_SAVE_DB4 == name && USER_PWD_SAVE_DB4 == pwd) {
// 登录成功
// 做很多的事情 校验成功信息等
responseResult("登录成功", 200)
// ...
} else {
// 登录失败
// 做很多的事情 登录失败的逻辑处理
// ...
responseResult("登录失败错了", 444)
}
}
21、Kotlin的函数类型作为返回类型
fun main() {
val r = show("学习KT语言")
// r 是show函数的 返回值
val niming_showMethod = showMethod("show")
// niming_showMethod 是 showMethod函数的返回值 只不过这个返回值 是一个 函数
// niming_showMethod == 匿名函数
println(niming_showMethod("hh",18))
}
fun show(info: String): Boolean {
println("我是show函数 info:$info")
return true
}
fun show2(info: String): String {
println("我是show函数 info:$info")
return "DDD"
}
fun show3(info: String): String {
println("我是show函数 info:$info")
return /*888*/ ""
}
// showMethod函数 再返回一个 匿名函数
fun showMethod(info: String): (String, Int) -> String {
println("我是show函数 info:$info")
// return 一个函数 匿名函数
return { name: String, age: Int ->
"我就是匿名函数:我的name:$name, age:$age"
}
}
22、Kotlin的匿名函数与具名函数
fun main() {
// 匿名函数
showPersonInfo("lisi", 99, '男', "学习KT语言") {
println("显示结果:$it")
}
// 具名函数 showResultImpl
showPersonInfo("wangwu", 89, '女', "学习C++语言", ::showResultImpl)
}
fun showResultImpl(result: String) {
println("显示结果:$result")
}
inline fun showPersonInfo(name: String, age: Int, sex: Char, study: String, showResult: (String) -> Unit) {
val str = "name:$name, age:$age, sex:$sex, study:$study"
showResult(str)
}
23、Kotlin的可空性特点
// TODO 第一种情况:默认是不可空类型,不能随意给null
var name: String = "hh"
// 提示:不能是非空类型String的值
// name = null
println(name)
// TODO 第二种情况:声明时指定为可空类型
var name2: String ?=null
// name2 = "hh"
println(name2)
24、Kotlin的安全调用操作符
fun main() {
var name: String? = "zhangsan"
// name = null
// name.capitalize() // name是可空类型的 可能是null,想要使用name,必须给出补救措施
val r = name?.capitalize() // name是可空类型的 如果真的是null,?后面这一段代码不执行,就不会引发空指针异常
println(r)
}
25、在Kotlin中使用带let的安全调用
fun main() {
var name: String? = null
name = "Derry"
name = ""
// name是可空类型的 如果真的是null,?后面这一段代码不执行,就不会引发空指针异常
val r =name?.let {
// it == name 本身
// 如果能够执行到这里面的,it 一定不为null
if (it.isBlank()) { // 如果name是空值 "" 没有内容
"Default"
} else {
"[$it]"
}
}
println(r)
}
26、Kotlin中的非空断言操作符特点
fun main() {
var name: String? = null
// name.capitalize() // name是可空类型的 可能是null,想要使用name,必须给出补救措施
// name = "hh"
// 补救措施 我们已经学习了 ?
val r = name!!.capitalize() // !! 断言 不管name是不是null,都执行,这个和java一样了
println(r)
// 结论:规矩:如果百分百能够保证name是有值的,那么才能使用断言 !!, 否则有Java 空指针异常的风险
}
27、Kotlin语法中对比使用if判断null值情况
fun main() {
var name: String? = null
name = "hh"
// name.capitalize() // name是可空类型的 可能是null,想要使用name,必须给出补救措施
if (name != null) { // if也算是补救措施,和Java一样了
val r = name.capitalize()
println(r)
} else {
println("name is null")
}
}
28、在Kotlin空合并操作符 ?:
fun main() {
var info: String? = "张三"
// info = null
// 空合并操作符 xxx ?: "原来你是null啊" "如果xxx等于null,就会执行 ?: 后面的区域"
println( info ?: "原来你是null啊" )
// let函数 + 空合并操作符
println(info?.let { "【$it】" } ?: "原来你是null啊2")
}
29、在Kotlin语法中异常处理与自定义异常特点
fun main() {
try {
var info: String? = null
checkException(info)
println(info!!.length)
}catch (e: Exception) {
println("啊呀:$e")
}
}
fun checkException(info: String?) {
info ?: throw CustomException()
}
class CustomException : IllegalArgumentException("你的代码太不严谨了")
30、Kotlin的先决条件函数
fun main() {
var value1: String ? = null
var value2: Boolean = false
// checkNotNull(value1) // java.lang.IllegalStateException: Required value was null.
// requireNotNull(value1) // java.lang.IllegalArgumentException: Required value was null.
require(value2) // java.lang.IllegalArgumentException: Failed requirement.
}
31、Kotlin的substring
fun main() {
val indexOf = INFO.indexOf('i')
println(INFO.substring(0, indexOf))
println(INFO.substring(0 until indexOf)) // KT基本上用此方式: 0 until indexOf
}
32、Kotlin的split操作
//kotlin解构指的是将对象的多个属性分别赋值给多个变量的过程
fun main() {
val jsonText = "dong,nan,xi,bei"
// list 自动类型推断成 list == List<String>
val list = jsonText.split(",")
// 直接输出 list 集合,不解构
println("分割后的list里面的元素有:$list")
// C++ 解构 Kt也有解构
val (v1, v2, v3, v4) = list
println("解构四个只读变量的值是:v1:$v1, v2:$v2, v3:$v3, v4:$v4")
}
33、Kotlin的replace完成加密解码操作
fun main() {
val sourcePwd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
println("原始密码是:$sourcePwd")
// 加密操作:就是把字符替换成数字 打乱了,就属于加密了
val newPwd = sourcePwd.replace(Regex("[AKMNO]")) {
it.value // 完全没有做任何事情
when(it.value) { // 这里的每一个字符 A B C D ...
"A" -> "9"
"K" -> "3"
"M" -> "5"
"N" -> "1"
"O" -> "4"
else -> it.value // 就啥事不做,直接返回 字符本身 A B C D ...
}
}
println("加密后的密码是:$newPwd")
// 解密操作
val sourcePwdNew = newPwd.replace(Regex("[9514]")) {
when(it.value) {
"9" -> "A"
"3" -> "K"
"5" -> "M"
"1" -> "N"
"4" -> "O"
else -> it.value // 就啥事不做,直接返回 字符本身 A B C D ...
}
}
println("解密后的密码是:$sourcePwdNew")
}
34、Kotlin的==与===比较操作
fun main() {
// == 值 内容的比较 相当于Java的equals
// === 引用的比较
val name1 : String = "Merry"
val name2 : String = "Merry"
val name3 = "ww"
// 小结:name1.equals(name2) 等价于 name1 == name2 都是属于 值 内容的比较
println(name1.equals(name2)) // java
println(name1 == name2) // kt
// 引用的比较
println(name1 === name2) // true
println(name1 === name3) // false
// 引用的比较 难度高一点点
val name4 = "merry".capitalize() // 修改成"Merry"
println(name4 === name1)
}
35、Kotlin的字符串遍历操作
fun main() {
val str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
str.forEach { c -> // 覆盖默认的it参数名,修改参数名为 c
// it == str的每一个字符 A B C D ...
// print("所有的字符是:$it ")
print("所有的字符是:$c ")
}
}
36、Kotlin中数字类型的安全转换函数
fun main() {
val number: Int = "666".toInt()
println(number)
// 字符串里面放入了Double类型,无法转换成Int,会奔溃
// val number2: Int = "666.6".toInt()
// println(number2)
// 解决上面奔溃的问题
val number2: Int? = "666.6".toIntOrNull()
println(number2)
val number3: Int? = "888".toIntOrNull()
println(number3)
val number4: Int? = "888.8".toIntOrNull()
println(number4 ?: "原来你是null啊")
// 小结:以后字符串有整形相关的转换,尽量用 toIntOrNull 此函数
}
37、Kotlin中Double转Int与类型格式化
fun main() {
println(65.4645654.toInt()) // 65 四舍五入
println(65.4645654.roundToInt()) // 65 四舍五入
println(65.8343433.roundToInt()) // 66 四舍五入
// 结论:用 roundToInt()函数,保证 Double ->转Int 持有四舍五入的效果
// r的类型: String
val r = "%.3f".format(65.8343433)
println(r)
}
38、Kotlin的apply内置函数
fun main() {
val info = "Lerry You Hao"
// 普通的方式
println("info字符串的长度是:${info.length}")
println("info最后一个字符是:${info[info.length -1]}")
println("info全部转成小写是:${info.toLowerCase()}")
println()
// apply内置函数的方式
// info.apply特点:apply函数始终是返回 info本身 String类型
val infoNew : String = info.apply {
// 一般大部分情况下,匿名函数,都会持有一个it,但是apply函数不会持有it,却会持有当前this == info本身
println("apply匿名函数里面打印的:$this")
println("info字符串的长度是:${length}")
println("info最后一个字符是:${this[length -1]}")
println("info全部转成小写是:${toLowerCase()}")
}
println("apply返回的值:$infoNew")
println()
// 真正使用apply函数的写法规则如下:
// info.apply特点:apply函数始终是返回 “info本身”,所以可以链式调用
info.apply {
println("长度是:$length")
}.apply {
println("最后一个字符是:${this[length -1]}")
true
true
true
}.apply {
println("全部转成小写是:${toLowerCase()}")
}
println()
// 普通写法
val file = File("D:\\a.txt")
file.setExecutable(true)
file.setReadable(true)
println(file.readLines())
println()
// apply写法
// 匿名函数里面 持有的this == file本身
/*val fileNew: File =*/ file.apply {
setExecutable(true)
}.apply {
setReadable(true)
}.apply {
println(file.readLines())
}
}
39、Kotlin的let内置函数
// 普通方式 对集合第一个元素相加
// let方式 对集合第一个元素相加
// 普通方式 对值判null,并返回
// let方式 对值判null,并返回
fun main() {
// 普通方式 对集合第一个元素相加
val list = listOf(6, 5, 2, 3, 5, 7)
val value1 = list.first() // 第一个元素
val result1 = value1 + value1
println(result1)
// let方式 对集合第一个元素相加
val result2 = listOf(6, 5, 2, 3, 5, 7).let {
// it == list集合
it.first() + it.first() // 匿名函数的最后一行,作为返回值,let的特点, 但是前面学的apply永远是返回info本身
/*true
true
true*/
}
println(result2)
println()
// 普通方式 对值判null,并返回
println(getMethod1(/*null*/ "Merry"))
// let方式 + 空合并操作符 对值判null,并返回
println(getMethod3(/*null*/ "Merry"))
}
// 普通方式 对值判null,并返回
fun getMethod1(value: String?) : String {
return if (value == null) "你传递的内容是null,你在搞什么飞机" else "欢迎回来${value}非常欢迎"
}
// 普通方式 简化版本
fun getMethod2(value: String?) = if (value == null) "你传递的内容是null,你在搞什么飞机" else "欢迎回来${value}非常欢迎"
// let方式 + 空合并操作符 对值判null,并返回
fun getMethod3(value: String?) : String {
return value?.let {
"欢迎回来${it}非常欢迎"
} ?: "你传递的内容是null,你在搞什么飞机"
}
// let方式 + 空合并操作符 对值判null,并返回 简化版本
fun getMethod4(value: String?) =
value?.let {
"欢迎回来${it}非常欢迎"
} ?: "你传递的内容是null,你在搞什么飞机"
40、Kotlin的run内置函数
// 1.run函数的特点 字符串延时
// 2.具名函数判断长度 isLong
// 3.具名函数监测合格 showText
// 4.具名函数增加一个括号 mapText
// 5.具名函数输出内容
fun main() {
val str = "Merry is OK"
val r1 : Float = str.run {
// this == str本身
true
5435.5f
}
println(r1)
// 下面是 具名函数 配合 run函数
// 2.具名函数判断长度 isLong
// 这个是属于 匿名函数 配合 run
str.run {
// this == str本身
}
// 这个是属于具名函数
// str.run(具名函数)
str
.run(::isLong) // this == str本身
.run(::showText) // this == isLong返回的boolean值
.run(::mapText)
.run(::println)
println()
// let函数持有it,run函数持有this 都可以很灵活的,把上一个结果值 自动给 下一个函数
str.let(::isLong) // it == str本身
.let(::showText) // it == isLong返回的boolean值
.let(::mapText) // it == str本身
.let(::println) // it == str本身
println()
// >>>>>>>>>>>>>>>>>>>>>> 上面全部都是具名函数调用给run执行 下面全部是 匿名函数调用给run执行
str
.run {
if (length > 5) true else false
}
.run {
if (this) "你的字符串合格" else "你的字符串不合格"
}
.run {
"【$this】"
}
.run {
println(this)
}
}
fun isLong(str: String) /* : Boolean */ = if (str.length > 5) true else false
fun showText(isLong: Boolean) /*: String */ = if (isLong) "你的字符串合格" else "你的字符串不合格"
fun mapText(getShow: String) /*: String */ = "【$getShow】"
41、Kotlin的with内置函数
fun main() {
val str = "李元芳"
// 具名操作
/*with(str) {
this == str本身
}*/
val r1 = with(str, ::getStrLen)
val r2 = with(r1, ::getLenInfo)
val r3 = with(r2, ::getInfoMap)
with(r3, ::show)
println()
// 匿名操作
with(with(with(with(str) {
length
}) {
"你的字符串长度是:$this"
}){
"【$this】"
}){
println(this)
}
}
fun getStrLen(str: String) = str.length
fun getLenInfo(len: Int) = "你的字符串长度是:$len"
fun getInfoMap(info: String) = "【$info】"
fun show(content: String) = println(content)
42、Kotlin的also内置函数
fun main() {
val str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
val r1 : String = str.also {
true
354543.4f
454
'C'
}
val r2 : Int = 123.also {
true
354543.4f
454
'C'
false
}
str.also {
// it == str本身
}
// 真正使用also函数的写法规则如下:
// str.also特点:also函数始终是返回 “str本身”,所以可以链式调用
str.also {
println("str的原始数据是:$it")
}.also {
println("str转换小写的效果是:${it.toLowerCase()}")
}.also {
println("结束了")
}
val file = File("D:\\a.txt")
// 匿名函数里面做的事情,和sourceFile无关,因为永远都是返回 file本身
val sourceFile = file.also {
file.setReadable(true)
file.setWritable(true)
println(file.readLines())
// 假设 做了很多很多的事情
// ...
}.also {
file.setReadable(true)
println(file.readLines())
// 假设 做了很多很多的事情
// ...
}.also {
file.setReadable(true)
println(file.readLines())
// 假设 做了很多很多的事情
// ...
}
// sourceFile没有任何影响
}
43、内置函数总结(apply/let/run/with)
(1)apply str.apply { this }
- apply函数返回类型,永远都是info本身,此条和also一模一样
- apply函数的匿名函数里面持有的是this==info本身,此条和run一模一样
(2)let str.let{it}
- let函数返回类型,是根据匿名函数最后一行的变化而变化,此条和run一模一样
- let函数的匿名函数里面持有的是it==info本身, 此条和also一模一样
(3)run str.run{this}
- run函数返回类型,是根据匿名函数最后一行的变化而变化,此条和let一模一样
- run函数的匿名函数里面持有的是this==info本身 ("aa".run{}) ,此条和apply一模一样
(4) with with(str)
- run函数返回类型,是根据匿名函数最后一行的变化而变化,此条和let一模一样
- run函数的匿名函数里面持有的是this==info本身 ("aa".run{}) ,此条和apply一模一样
(5)str.also{}
- also函数返回类型,永远都是info本身 此条和apply一模一样
- also函数的匿名函数里面持有的是it==info本身 ("aa".run{}) ,此条和let一模一样
44、Kotlin的takeIf内置函数 str.takeIf{true/false}?: "hh"
一般大部分情况下,都是 takeIf + 空合并操作符 = 一起使用
fun main() {
val result = checkPermissionAction("Root2", "!@#$")
// println("欢迎${result}")
if (result != null) {
println("欢迎${result}")
} else {
println("你的权限不够")
}
// name.takeIf { true/false }
// true: 直接返回name本身
// false: 直接放回null
// 真正的用途
println(checkPermissionAction2("Root", "!@#$"))
// 小结:一般大部分情况下,都是 takeIf + 空合并操作符 = 一起使用
}
// 前端
public fun checkPermissionAction(name: String, pwd: String) : String? {
return name.takeIf { permissionSystem(name, pwd) }
}
// takeIf + 空合并操作符
public fun checkPermissionAction2(name: String, pwd: String) : String {
return name.takeIf { permissionSystem(name, pwd) } ?: "你的权限不够"
}
// 权限系统
private fun permissionSystem(username: String, userpwd: String) : Boolean {
return if (username == "Root" && userpwd == "!@#$") true else false
}
45、Kotlin的takeUnless内置函数
takeIf 和 takeUnless 功能是相反的
name.takeIf { true/false } true:返回name本身,false返回null
name.takeUnless { true/false } false:返回name本身,true返回null
class Manager {
private var infoValue: String? = null
fun getInfoValue() /* : String? */ = infoValue
fun setInfoValue(infoValue: String) {
this.infoValue = infoValue
}
}
fun main() {
val manager = Manager()
/*
"Derry".takeIf { *//*it == "Merry"*//* }
"Derry".takeUnless { *//*it == "Merry"*//* }
*/
// manager.setInfoValue("AAA")
// 小结:takeUnless+it.isNullOrBlank() 一起使用,可以验证字符串有没有初始化等功能
val r = manager.getInfoValue().takeUnless { it.isNullOrBlank() } ?: "未经过任何初始化值"
println(r)
}
46、Kotlin的List创建与元素获取学习
- 普通取值方式: 索引
- 防止奔溃取值方式: getOrElse getOrNull
fun main() {
val list = listOf("Merry", "Zhangsan", "Lisi", "Wangwu")
// 普通取值方式: 索引 内部是运算符重载 [] == get
println(list[0])
println(list[1])
println(list[2])
println(list[3])
// println(list[4]) // 奔溃 java.lang.ArrayIndexOutOfBoundsException: 4
println()
// 我们写KT代码,一定不会再出现,空指针异常,下标越界异常
// 防止奔溃取值方式: getOrElse getOrNull
println(list.getOrElse(3) {"越界"})
println(list.getOrElse(4) {"你越界了"})
println(list.getOrElse(4402) {"你越界了啊"})
println()
println(list.getOrNull(1))
println(list.getOrNull(4))
println(list.getOrNull(111))
// getOrNull + 空合并操作符
println(list.getOrNull(222) ?: "你越界了哦哦")
// 小结:开发过程中,尽量使用 getOrElse 或 getOrNull,才能体现KT的亮点
}
47、Kotlin的可变List集合学习
可变的集合
不可变集合 to 可变集合 toMutableList()
可变集合 to 不可变集合 toList()
fun main() {
// 可变的集合
val list = mutableListOf("Merry", "Zhangsna", "Wangwu")
// 可变的集合,可以完成可变的操作
list.add("赵六")
list.remove("Wangwu")
println(list)
// 不可变集合 to 可变集合
val list2 = listOf(123, 456, 789)
// 不可以的集合,无法完成可变的操作
// list2.add
// list2.remove
val list3 : MutableList<Int> = list2.toMutableList()
// 可变的集合,可以完成可变的操作
list3.add(111)
list3.remove(123)
println(list3)
// 可变集合 to 不可变集合
val list4: MutableList<Char> = mutableListOf('A', 'B', 'C')
// 可变的集合,可以完成可变的操作
list4.add('Z')
list4.remove('A')
println(list4)
val list5: List<Char> = list4.toList()
// 不可以的集合,无法完成可变的操作
/*list5.add
list5.remove*/
}
48、Kotlin的mutator函数学习
- mutator += -= 操作
- removeIf
fun main() {
// 1.mutator += -= 操作
val list : MutableList<String> = mutableListOf("Merry", "MerryAll", "MerryStr", "Zhangsan")
list += "李四" // mutator的特性 += -+ 其实背后就是 运算符重载而已
list += "王五"
list -= "Merry"
println(list)
// 2.removeIf
// list.removeIf { true } // 如果是true 自动变量整个可变集合,进行一个元素一个元素的删除
list.removeIf { it.contains("Merr") } // 过滤所有的元素,只要是有 Merr 的元素,就是true 删除
println(list)
}
49、Kotlin的List集合遍历学习
fun main() {
val list = listOf(1, 2, 3, 4, 5, 6, 7)
println(list) // 输出list详情而已,这个不是遍历集合
// 第一种 遍历方式:
for (i in list) {
print("元素:$i ")
}
println()
// 第二种 遍历方式:
list.forEach {
// it == 每一个元素
print("元素:$it ")
}
println()
// 第三种 遍历方式:
list.forEachIndexed { index, item ->
print("下标:$index, 元素:$item ")
}
}
50、Kotlin的解构语法过滤元素学习
- 集合配合解构语法
- 反编译看Java给三个变量赋值的代码
- 解构屏蔽接收值
fun main() {
val list: List<String> = listOf("李元霸", "李小龙", "李连杰")
val(value1, value2, value3) = list
// value1 = "" val只读的
println("value1:$value1, value2:$value2, value3:$value3")
var(v1, v2, v3) = list
// v1 = "OK"
println("v1:$v1, v2:$v2, v3:$v3")
// 用_内部可以不接收赋值,可以节约一点性能
val(_ , n2, n3) = list
// println(_) _不是变量名,是用来过滤解构赋值的,不接收赋值给我
println("n2:$n2, n3:$n3")
}
51、Kotlin的Set创建与元素获取
- set 定义 不允许重复
- 普通方式elementAt 会越界奔溃
- elementAtOrElse elementAtOrNull
fun main() {
val set: Set<String> = setOf("lisi", "wangwu", "zhaoliu", "zhaoliu") // set集合不会出现重复元素的
println(set)
// set[0] 没有这样 [] 的功能 去Set集合元素
println(set.elementAt(0)) // [0]
println(set.elementAt(1))
println(set.elementAt(2))
// println(set.elementAt(3)) // [3] 奔溃 会越界
// println(set.elementAt(4)) // [4] 奔溃 会越界
println()
// 使用 list 或 set 集合,尽量使用 此方式,防止越界奔溃异常
println(set.elementAtOrElse(0) {"越界了"})
println(set.elementAtOrElse(100) {"越界了了"})
println(set.elementAtOrNull(0))
println(set.elementAtOrNull(111))
// OrNull + 空合并操作符 一起使用
println(set.elementAtOrNull(88) ?: "你越界啦啊")
}
52、Kotlin的可变Set集合
fun main() {
val set : MutableSet<String> = mutableSetOf("A", "B")
set += "C"
set += "D"
set -= "D"
set.add("E")
set.remove("E")
println(set)
}
53、Kotlin的集合转换与快捷函数学习
- 定义可变list集合
- List 转 Set 去重
- List 转 Set 转 List 也能去重
- 快捷函数去重 distinct
fun main() {
val list : MutableList<String> = mutableListOf("A", "A", "A", "B", "C") // list 可以重复元素
println(list)
// List 转 Set 去重
val set /*: Set<String>*/ = list.toSet()
println(set)
// List 转 Set 转 List 也能去重
val list2 /*: List<String>*/ = list.toSet().toList()
println(list2)
// 快捷函数去重 distinct
println(list.distinct()) // 内部做了:先转变成 可变的Set结合 在转换成 List集合
println(list.toMutableSet().toList()) // 和上面代码等价
}
54、Kotlin中的数组类型
Kotlin语言中的各种数组类型,虽然是引用类型,背后可以编译成Java基本数据类型
IntArray intArrayOf
DoubleArray doubleArrayOf
LongArray longArrayOf
ShortArray shortArrayOf
ByteArray byteArrayOf
FloatArray floatArrayOf
BooleanArray booleanArrayOf
Array<对象类型> arrayOf 对象数组
// 1.intArrayOf 常规操作的越界奔溃
// 2.elementAtOrElse elementAtOrNull
// 3.List集合转 数组
// 4.arrayOf Array<File>
fun main() {
// 1.intArrayOf 常规操作的越界奔溃
val intArray /*: IntArray*/ = intArrayOf(1, 2, 3, 4, 5)
println(intArray[0])
println(intArray[1])
println(intArray[2])
println(intArray[3])
println(intArray[4])
// println(intArray[5]) // 奔溃:会越界异常
println()
// 2.elementAtOrElse elementAtOrNull
println(intArray.elementAtOrElse(0) { -1 })
println(intArray.elementAtOrElse(100) { -1 })
println(intArray.elementAtOrNull(0))
println(intArray.elementAtOrNull(200))
// OrNull + 空合并操作符 一起来用
println(intArray.elementAtOrNull(666) ?: "你越界啦啊啊啊")
println()
// 3.List集合转 数组
val charArray /*: CharArray*/ = listOf('A', 'B', 'C').toCharArray()
println(charArray)
// 4.arrayOf Array<File>
val objArray /*: Array<File>*/ = arrayOf(File("AAA"), File("BBB"), File("CCC"))
}
55、Kotlin的Map的创建
fun main() {
val mMap1 : Map<String, Double> = mapOf<String, Double>("A" to(534.4), "B" to 454.5)
val mMap2 = mapOf(Pair("A", 545.4), Pair("B", 664.4))
// 上面两种方式是等价的哦
}
56、Kotlin的读取Map的值
- 方式一 [] 找不到会返回null
- 方式二 getOrDefault
- 方式三 getOrElse
- 方式四 getValue()与Java一样 会奔溃
fun main() {
val mMap /*: Map<String, Int>*/ = mapOf("A" to 123,"B" to 654)
// 方式一 [] 找不到会返回null
println(mMap["A"]) // 背后对[] 运算符重载了
println(mMap["B"])
println(mMap.get("A")) // get 与 [] 完完全全等价的
println(mMap["XXX"]) // map通过key找 如果找不到返回null,不会奔溃
println()
// 方式二 getOrDefault
println(mMap.getOrDefault("A", -1))
println(mMap.getOrDefault("C", -1))
// 方式三 getOrElse
println(mMap.getOrElse("A") {-1})
println(mMap.getOrElse("C") {-1})
println()
// 方式四 getValue 与Java一样 会奔溃 尽量不要使用此方式
println(mMap.getValue("A"))
println(mMap.getValue("XXX"))
// map获取内容,尽量使用 方式二 方式三
}
57、Kotlin的遍历Map
fun main() {
val map /*: Map<String, Int>*/ = mapOf(Pair("A", 123), Pair("B", 456), "C" to 789)
// 第一种方式:
map.forEach {
// it 内容 每一个元素 (K 和 V) 每一个元素 (K 和 V) 每一个元素 (K 和 V)
// it 类型 Map.Entry<String, Int>
println("K:${it.key} V:${it.value}")
}
println()
// 第二种方式:
map.forEach { key: String, value: Int ->
// 把默认的it给覆盖了
println("key:$key, value:$value")
}
println()
// 第三种方式:
map.forEach { (k /*: String*/, v /*: Int*/) ->
println("key:$k, value:$v")
}
println()
// 第四种方式:
for (item /*: Map.Entry<String, Int>*/ in map) {
// item 内容 每一个元素 (K 和 V) 每一个元素 (K 和 V) 每一个元素 (K 和 V)
println("key:${item.key} value:${item.value}")
}
}
58、Kotlin的可变Map集合
- 可变集合的操作 += [] put
- getOrPut 没有的情况
- getOrPut 有的情况
fun main() {
// 1.可变集合的操作 += [] put
val map : MutableMap<String, Int> = mutableMapOf(Pair("A", 123), "B" to 456, Pair("Dee", 789))
// 下面是可变操作
map += "AAA" to(111)
map += "BBB" to 1234
map -= "A"
map["CCC"] = 888
map.put("DDD", 999) // put 和 [] 等价的
// 2.getOrPut 没有有的情况
// 如果整个map集合里面没有 FFF的key 元素,我就帮你先添加到map集合中去,然后再从map集合中获取
val r: Int = map.getOrPut("FFF") { 555 }
println(r)
println(map["FFF"]) // 他已经帮你加入进去了,所以你可以获取
// 3.getOrPut 有的情况
val r2 = map.getOrPut("B") {666} // 发现Derry的key是有的,那么就直接获取出来, 相当于666备用值就失效了
println(r2)
}
59、Kotlin的定义类与field关键字
class KtBase {
var name = "A"
get() = field
set(value) {
field = value
}
/* 背后做的事情:
@NotNull
private String name = "A";
public void setName( @NotNull String name) {
this.name = name;
}
@NotNull
public String getName() {
return this.name;
}
*/
var value = "ABCDEFG"
// 下面的隐式代码,不写也有,就是下面这个样子
get() = field
set(value) {
field = value
}
var info = "abcdefg ok is success"
get() = field.capitalize() // 把首字母修改成大写
set(value) {
field = "**【$value】**"
}
/* 背后做的事情:
@NotNull
private String info = "abcdefg ok is success";
public void setInfo( @NotNull String info) {
this.info = "**【" + info + "】**";
}
@NotNull
public String getInfo() {
return StringKt.capitalize(this.info)
}
*/
}
// public final class KtBaseKt { 下面的main函数 }
fun main() {
// 背后隐式代码:new KtBase().setName("C");
KtBase().name = "C"
// 背后隐式代码:System.out.println(new KtBase().getName());
println(KtBase().name)
println(">>>>>>>>>>>>>>>>>>")
// 背后隐式代码:System.out.println(new KtBase().getInfo());
println(KtBase().info)
// 背后隐式代码:new KtBase().setInfo("学习KT");
KtBase().info = "学习KT"
}
第二部分: