package com.zsw.myandroidlearnapplication.kotlin
import java.io.File
import kotlin.math.roundToInt
/**
*@author zengsuwa
*@date 2023/4/19
*@desc
*
*/
//TODO 内置函数的总结
// let 函数返回类型是根据匿名函数最后一行的变化而变化,
// let函数的匿名函数持有的是it == 集合本身
// apply
// apply函数返回值,一直都是info本身
// apply函数里面持有的是this == info本身
/** todo Kotlin内置函数总结
* 1.apply info.apply
* apply 函数返回类型用于都是info本身
* apply 函数的匿名函数里面持有的是this == info本身
*
* 2.let str.let
* let 函数的返回类型是根据 匿名函数的最后一行变化而变化
* let 函数的匿名函数里面持有的是it == 集合本身
* 3.run str.run
* run 函数的返回类型是根据 匿名函数的最后一行变化而变化 这一点跟let一样
* run 函数的匿名函数里面持有的是this == str本身(谁点出来的就持有谁) 这一点跟apply一样
* 4.with with(str) with 和run基本上一样,就是使用方法上不一样
* with 函数的返回类型是根据 匿名函数的最后一行变化而变化 这一点跟let一样
* with 函数的匿名函数里面持有的是this == str本身(谁点出来的就持有谁) 这一点跟apply一样
*
* 5.also str.also
* 函数返回类型用于都是str本身 这一点跟apply一样
* 函数的匿名函数里面持有的是it == str本身 这一点跟let一样
*
* 6.takeIf
* 如果takeIf里面返回的是false 那么这个表达式返回的是null ,如果takeIf里面返回的是true,那么这个表达式返回的是name本身
* name.takeIf {true/false}
* 函数的匿名函数里面持有的是it == name本身 这一点跟let一样
*
* 7.takeUnless
* 如果takeUnless里面返回的是false 那么这个表达式返回的是name本身 ,如果takeUnless里面返回的是true,那么这个表达式返回的是null
* takeIf和takeUnless的功能是相反的
* name.takeUnless {true/false}
*
*/
class Base01 {
}
private fun add(number: Int, number2: Int): Int {
return number + number2
}
//TODO 匿名函数 == lambda表达式
var methodAction = { num1: Int, num2: Int, result: String ->
var sum = num1 + num2
result + sum
}
//返回Any类型 类似于Java中的Object
val methodAction2 = { num: Int ->
when (num) {
1 -> "星期一"
2 -> "星期二"
3 -> "星期三"
4 -> "星期四"
5 -> "星期五"
6 -> "星期六"
7 -> "星期日"
else -> -1
}
}
//在Java中写法
// public void login(String username,String pwd,CallBack callback){
// String result = httpRequest(username,pwd);
// callback(result)
// }
//resultCallback 可以等同于Java接口回调的作用
//在函数中定义的参数是函数的函数
fun login(username: String, pwd: String, resultCallback: (result: String, Int) -> Unit) {
if (username == null || pwd == null) {
TODO("用户名或密码为空,程序不会往下执行")
}
if (webService(username, pwd)) {
resultCallback("登录成功", 200)
} else {
resultCallback("登录失败", 400)
}
}
//这个函数里面有使用lambda表达式作为参数所以需要声明成内联函数
// 如果此函数不使用内联,在调用端会生成多个对象来完成对lambda的调用(会造成性能损耗)
// Tools->Kotlin ->show Kotlin Bytecode ->Decompile查看字节码可看到转成了Function2对象
// login2("xiaoming", "123456", (Function2)null.INSTANCE);
// 如果此函数使用内联,相当于C++ #define 宏定义 宏替换 会把代码替换到调用处,调用处没有任何函数开辟 对象开辟的损耗
//小结:如果函数有lambda 尽量使用inline关键字 内联 这样内部会做优化减少函数开辟,对象开辟的损耗
//main()函数里面字节码转换login2的调用处变成如下代码
//
//String username$iv = "xiaoming";
//String pwd$iv = "123456";
//int $i$f$login2 = false;
//short code;
//String result;
//boolean var5;
//String var6;
//if (webService(username$iv, pwd$iv)) {
// code = 200;
// result = "登录成功";
// var5 = false;
// var6 = result + ",状态码" + code;
// System.out.println(var6);
//} else {
// code = 400;
// result = "登录失败";
// var5 = false;
// var6 = result + ",状态码" + code;
// System.out.println(var6);
//}
inline fun login2(username: String, pwd: String, resultCallback: (result: String, Int) -> Unit) {
if (username == null || pwd == null) {
TODO("用户名或密码为空,程序不会往下执行")
}
if (webService(username, pwd)) {
resultCallback("登录成功", 200)
} else {
resultCallback("登录失败", 400)
}
}
//这个函数里面没有使用lambda表达式作为参数所以不需要声明成内联函数
fun webService(username: String, pwd: String): Boolean {
return username == "xiaoming" && pwd == "123456"
}
fun resultMethod(msg: String, code: Int) {
println("$msg,状态码$code")
}
//返回一个函数
fun returnMethod(info: String): (String, Int) -> String {
println("info=$info")
return { name: String, age: Int ->
val ageStr = when (age) {
in 1..18 ->
"小孩"
in 20..60 ->
"成年人"
else ->
"老人"
}
"name=$name,age=${age}是个$ageStr"
}
}
//入参为函数
inline fun method1(name: String, age: Int, sex: Char, canshuMethod: (info: String) -> Unit) {
val info1 = "name:$name,age:$age,sex:$sex"
canshuMethod(info1)
}
fun method2(info: String) {
println("hahah*********info:$info")
}
fun checkException(info: String?) {
info ?: throw CustomException() //忘记加 throw 就不会抛出
}
class CustomException : java.lang.IllegalArgumentException("你的代码不严谨")
fun isLong(str: String) = str.length > 5
fun showText(isLong: Boolean) = if (isLong) "你的字符串合格" else "你的字符串不合格"
fun mapText(str: String) = "[$str]"
fun checkPermissionAction(name: String, pwd: String): String? {
//如果takeif里面返回的是false 那么这个表达式返回的是null ,如果takeIf里面返回的是true,那么这个表达式返回的是name本身
//name.takeIf {true/false}
return name.takeIf {
checkPermission(it, pwd)
}
}
//一般大部分情况下takeIf都跟空合并操作符一起使用
fun checkPermissionAction2(name: String, pwd: String): String {
//如果takeif里面返回的是false 那么这个表达式返回的是null ,如果takeIf里面返回的是true,那么这个表达式返回的是name本身
//name.takeIf {true/false}
return name.takeIf {
checkPermission(it, pwd)
} ?: "您的权限不够"
}
private fun checkPermission(name: String, pwd: String): Boolean {
return (name == "root" && pwd == "123456")
}
class Manager {
private var infoValue: String? = null
fun getInfoValue() = infoValue
}
fun main() {
//会提示不能是非空类型的String值
var name = "hahah"
// name = null
//声明指定为可空类型
var name2: String? = "xiaoming"
name2 = null
//?: 空合并操作符
val info = name2 ?: "这个值为空"
println(info)//打印 这个值为空
//capitalize() 首字母大写的作用
//补救措施
//1.?
name2?.capitalize()//name2 为可空类型,?.空安全运算符 表示如果name2为空,那么后面那一节不执行
//2. !!
try {
// checkException(name2)//com.zsw.myandroidlearnapplication.kotlin.CustomException: 你的代码不严谨
//TODO 可以使用checkNotNull() requireNotNull 检查是否value为空,为空则抛出异常
// require检查是否value为false 为false则抛出异常
// checkNotNull(name2)//检查value是否不为空, java.lang.IllegalStateException: Required value was null
// requireNotNull(name2)//检查value是否不为空 java.lang.IllegalArgumentException: Required value was null.
val value = false
require(value)//如果值为false则抛出异常 java.lang.IllegalArgumentException: Failed requirement.
println(name2!!.capitalize()) //!! 非空断言运算符 表示name2必不为空, 如果为空就会引发空指针
} catch (e: Exception) {
// e.printStackTrace()
println(e)
println("哎呀${e.message}")
}
val info3 = "hello world!"
val indexOf = info3.indexOf("w")
//均输出 hello
//hello+空格
println(info3.substring(0, indexOf))//这两种写法是等价的
println(info3.substring(0 until indexOf))//KT 中一般都使用这种方式
//3。if
if (name2 != null) {
name2.capitalize()
} else {
println("name2 is null")
}
//TODO 在kt中使用带let的安全调用
//?后面不执行,不会引发空指针
val r = name2?.let {
//能执行到这里说明 name2肯定不为空 isBlank 是"" 没有内容
if (name2.isBlank()) {
"Default"
} else {
"[$it]"
}
}
println(r)
//{ result, code ->
// println("$result,状态码$code")
// }
//这一部分是Login函数中定义的函数的实现
//lambda表达式 可以写在括号里面也可以写在括号外面
//第一种方式
login("xiaoming", "123456", resultCallback = { result: String, code: Int ->
println("$result,状态码$code")
})
//第二种方式
login2("xiaoming", "123456", { result: String, code: Int ->
println("$result,状态码$code")
})
//第三种方式 最优
login("xiaoming", "123456") { result, code ->
println("$result,状态码$code")
}
//TODO 第四种方式 函数引用 ::
// lambda属于函数类型的对象 ,需要把resultMethod普通函数转变成 函数类型的对象(函数引用)在使用函数的前面加上::
// 传递了一个函数进来 resultMethod
login2("xiaoming", "123456", ::resultMethod)
//定义了 obj 这个变量来接收函数类型的对象
val obj = ::resultMethod
val obje = obj
login2("xiaoming", "123456", obje)
println("4 + 5 = ${add(4, 5)}")
println(methodAction(2, 5, "两数之和为"))
//放开TODO的注释 会抛出这个异常
// Exception in thread "main" kotlin.NotImplementedError:
// An operation is not implemented: 出现问题,程序不会往下执行
// TODO("出现问题,程序不会往下执行")
println(methodAction2(6))
val nimingMethod = returnMethod("xiaoming")//立即打印结果 info=xiaoming
println(nimingMethod("zhangsan", 12))//调用这一行才会打印
//入参为匿名函数
method1("zhangsan", 14, '男') {
println(it)
}
//入参为具名函数 需要使用:: 把普通函数转换为 函数类型的对象
method1("wangwu", 20, '男', ::method2)
val jsonText = "zhangsan,lisi,wangwu,zhaoliu"
//根据","截取成List<String>集合
val list = jsonText.split(",")
//直接输出list 不解构
println("分割后的list里面的元素有:$list")
//c++ 解构 KT也有解构
//这里面如果加一个v5会报错 Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
val (v1, v2, v3, v4) = list
//解构后的四个只读变量为:v1:zhangsan,v2:lisi,v3:wangwu,v4:zhaoliu
println("解构后的四个只读变量为:v1:$v1,v2:$v2,v3:$v3,v4:$v4")
//45.TODO kotlin replace 完成加密解密操作
val password = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
println("原密码:$password")
//加密操作就是把字符串替换成数字 打乱了 就属于加密了
val jiamipwd = password.replace(Regex("[AKMNO]")) {
// it.value//如果这里是返回这个,表示什么事情都没做,没加密 it.value 是取出password中通过正则表达式的每个字符,然后返回有点类似与遍历当前字符串的字符
print("${it.value} ")//打印的是: A K M N O
when (it.value) {
"A" -> "9"
"K" -> "3"
"M" -> "1"
"N" -> "5"
"O" -> "4"
else ->
it.value
}
}
println()
println("加密后的密码:$jiamipwd")
val jiemiPwd = jiamipwd.replace(Regex("[93154]")) {
when (it.value) {
"9" -> "A"
"3" -> "K"
"1" -> "M"
"5" -> "N"
"4" -> "O"
else -> it.value
}
}
println("解密后的密码:$jiemiPwd")
//== 值内容的比较 相当于Java的equals
//=== 引用的比较
val name3 = "Derry"
val name4 = "Derry"
println(name3 == name4) //true
println(name3 === name4) //true 其实指向的都是同一个字符串常量池中的这个常量
val name6 = "jerry"
println(name3 == name6)
println(name3 === name6)
val name5 = "derry".capitalize()
println(name5)//Derry
println(name3 === name5)//false
password.forEach {
print("$it ")
}
println()
val num1 = "888".toInt()
// val num2 = "888.8".toInt()//会抛异常 Exception in thread "main" java.lang.NumberFormatException: For input string: "888.8"
val num3: Int? = "888.8".toIntOrNull()//不会抛异常 值为null
//TODO 以后字符串转Int尽量都使用toIntOrNull此函数
println(65.469778.toInt())//65
println(65.4692873.roundToInt())//65
println(65.579890.roundToInt())//66
//roundToInt Double转Int四舍五入
//r 的类型字符串类型 保留小数点后三位数 也会四舍五入
val rel = "%.3f".format(65.4697873)
val rel2 = "%.3f".format(65.4692873)
println(rel)//65.470
println(rel2)//65.470
val info2 = "nihao XiaoMing"
println("info长度${info2.length}")
println("info最后一个字符是${info2[info2.length - 1]}")
println("info的全部转成小写是${info2.lowercase()}")
//info2.apply 始终返回info2 本身
val info4 = info2.apply {
//大部分情况下,匿名函数都会持有一个it,但是apply()函数不会持有it,却会持有当前this == info2 本身
println("info长度${length}")
println("info最后一个字符是${this[length - 1]}")
println("info的全部转成小写是${lowercase()}")
}
println(info4)
info2.apply {
println("info长度${length}")
}.apply {
println("info最后一个字符是${this[length - 1]}")
}.apply {
println("info的全部转成小写是${lowercase()}")
}
val file = File("/Users/sunnyzeng/Desktop/a.txt")
//普通方式
file.setExecutable(true)
file.setReadable(true)
println(file.readLines())
//apply方式
val file2: File = file.apply {
setExecutable(true)
setReadable(true)
println(readLines())
true
}
val sum = listOf(6, 5, 4, 3, 2, 1).let {
println(it)//[6, 5, 4, 3, 2, 1]
it.first() + it.first()//匿名函数的最后一行作为返回值,let的特点,但是前面学的apply永远返回info本身
}
println(sum)
var name8: String? = "null"
name8 = null
name8?.let {
}
val str3 = "derry is ok"
//这个属于匿名函数配合run
str3.run {
// this == str3
}
// 这个是属于具名函数配合run
// str3.run(具名函数)
println("******* run ********")
str3.run(::isLong) //this 为String ; return Boolean
.run(::showText)// this 为Boolean ; return String
.run(::mapText)//this 为String ; return String
.run(::println)//this 为 String ;return Uint
println("******* let ********")
str3.let(::isLong) //it 为String ; return Boolean
.let(::showText)// it 为Boolean ; return String
.let(::mapText)//it 为String ; return String
.let(::println)//it 为 String ;return Uint
println("******* with ********")
val r1 = with(str3, ::isLong)
val r2 = with(r1, ::showText)
val r3 = with(r2, ::mapText)
with(r3, ::println)
//以上是具名函数配合run,以下是匿名函数配合run
str3.run { length > 5 }
.run { if (this) "run 你的字符串合格" else "你的字符串不合格" }
.run { "[$this]" }
.run { println(this) }
str3.let { it.length > 5 }
.let { if (it) "let 你的字符串合格" else "你的字符串不合格" }
.let { "[$it]" }
.let { println(it) }
with(with(with(with(str3) {
length > 5
})
{
if (this) "with 你的字符串合格" else "你的字符串不合格"
}) {
"[$this]"
}) {
println(this)
}
val result: String = str3.also {
123
}
//also 匿名函数永远返回的都是他自己
password.also {
println("password的源数据是$it")
}.also {
println("password转换成小写的效果是${it.lowercase()}")
}.also { println(it) }
val re1 = checkPermissionAction("root", "123456")
if (rel != null) {
println("欢迎${re1}尊贵的用户登录超级系统,拥有超级权限")
} else {
println("您的权限不够")
}
println(checkPermissionAction2("root1", "123456"))
val manager = Manager()
//takeUnless+ it.isNullOrBlank 一起使用可以验证字符串有没有初始化等功能
val take11 = manager.getInfoValue().takeUnless { it.isNullOrBlank() } ?: "没有任何的初始化操作"
val take22 = manager.getInfoValue().takeIf { !it.isNullOrBlank() } ?: "没有任何的初始化操作"
println(take11)
println(take22)
}
kotlin 练习1
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...