上节学习了变量的可空与非空类型的定义,以及如何进行操作。那么对于字符串、数字的相关操作与Java有多大区别呢,有哪些常用的函数呢,一起开始本节的学习。
一 字符串操作
字符串可以说是我们平常操作得非常多的类型之一,显示、截取、拼接、变化等等。
1、substring
字符串截取,substring函数支持IntRange类型的参数,until创建的范围不包括上限值。
val str = "Hello World"
val index = str.indexOf('d')
println("size=${str.length} index=${index}")
val str0 = str.substring(0 until index)
println(str0)
//输出结果
//size=11 index=10
//Hello Worl
可以看到,字符串长度为11,下标为0-10,当截取的时候,实际截取了0-9位置的下标。这也就解释了until创建的范围不包括上限值。
2、split函数
split函数返回的是List集合数据,List集合又支持解构语法,它允许你在一个表达式里给多个变量赋值。
fun splitFun(){
val str = "java,kotlin,php,python"
val list = str.split(',')
println(list)
//这里就式结构语法
val (one,two,three,four) = str.split(',')
println("$one $two $three $four")
}
//结果
[java, kotlin, php, python]
java kotlin php python
在Java中split返回的是一个数组,而Kotlin返回的是一个List。至于这个解构语法,就理解为直接赋值到变量里吧,就不用一个个去进行赋值操作了。
3、replace
fun replaceFun(){
val str = "Hello World"
//第一个参数是正则表达式,决定要替换哪些字符
//第二个参数是一个匿名函数,确定要替换的规则
val str0 = str.replace(Regex("[Hlo]")){
when(it.value){
"H" -> "1"
"l" -> "2"
"o" -> "3"
else -> it.value
}
}
//这个是为了与上面的进行对比,当lambda表达式在是最后一个参数的时候可以直接写在大括号里面,就是看着像函数体的意思,前面有说过,还记得么
val str1 = str.replace(Regex("[Hlo]"),{
when(it.value){
"H" -> "1"
"l" -> "2"
"o" -> "3"
else -> it.value
}
})
println(str)
println(str0)
println(str1)
}
//结果
Hello World
1e223 W3r2d
1e223 W3r2d
4、字符串比较
在Java中双等号比较引用,equals比较值。而在Kotlin中,用双等号检查两个字符串中的字符是否匹配,用三等号检查两个变量是否指向内存堆上的同一对象。这点区别还是蛮大的。
fun compareFun(){
val str0 = "Hello World"
val str1 = "hello World".capitalize()
println("$str0 $str1")
println(str0 == str1)
println(str0 === str1)
}
//输出结果
Hello World Hello World
true
false
5、forEach
遍历字符
fun forEachFun(){
val str0 = "Hello World"
str0.forEach {
print("$it *")
}
}
//输出结果
H *e *l *l *o * *W *o *r *l *d *
二 数字操作
1、安全转换函数
Kotlin提供了toDoubleOrNull和toIntOrNull这样的安全转化函数,如果数值不能正确转化,则返回null
fun safeConvert(){
//这句代码是无法正常转换的,会抛出NumberFormatException异常
// val num0 = "H".toInt()
//我们可以使用安全转化函数来处理,返回null而不是抛出异常
val num1 = "H".toIntOrNull()
println(num1)
}
2、Double类型格式化
格式化字符串是一串特殊字符,它决定该如何格式化数据
fun formatFun(){
val str0 = "%.2f".format(3.1415926)
println(str0)
}
//结果
3.14
思考:这种格式化方式是否会进行四舍五入的操作呢?哈哈,自己去测试下吧
3、Double转Int
fun d2i(){
println(3.9415926.toInt())
println(3.4415926.roundToInt())
println(3.5415926.roundToInt())
}
//结果
3
3
4
嗯,这个不多说了,看结果自知
三 标准函数库
1、apply
apply函数可以看作一个配置函数,你可以传入一个接收者然后经过一系列配置以使用它。如果提供lambda给apply函数指向,它会返回配置好的接收者。
fun applyFun(){
val person1 = Person("Jack",20)
println(person1)
person1.name = "Jacky"
println(person1)
val person2 = Person("Lucy",18).apply {
println(this)
age = 19
}
println(person2)
}
data class Person(var name:String, var age:Int)
//执行结果
Person(name=Jack, age=20)
Person(name=Jacky, age=20)
Person(name=Lucy, age=18)
Person(name=Lucy, age=19)
嗯,先理解为将要操作的动作可以放在一起进行,然后在将设置之后的数据返回出去吧。
2、let
let函数能使某个变量作用于lambda表达式里,让it关键字能引用它。let与apply比较,let会把接收者传给lambda,而apply什么都不传。匿名函数执行完,apply会返回当前接收者,而let会返回lambda表达式的最后一行
fun letFun(){
val result = Person("Jack",20).let {
it.age = 18
"我叫${it.name},今年${it.age}岁"
}
println(result)
}
//执行结果
我叫Jack,今年18岁
3、run
嗯,run这个从作用域上看与apply挺像,但接收的结果与let挺像,先理解为他们的结合体吧
fun runFun(){
val person = Person("Jack",18)
val result = person.run {
"Hello,${name}"
}
println(result)
}
//执行结果
Hello,Jack
4、with
with函数是run的变体,他们的功能行为是一样的,但with的调用方式不一样,调用with时需要值参作为其第一个参数传入
fun withFun(){
val person = Person("Jack",18)
val result = with(with(person){
"Hello,${name}"
}){
"上次执行的结果是:${this}"
}
println(result)
}
//执行结果
上次执行的结果是:Hello,Jack
好吧,我承认看到这样的嵌套代码你一定会很晕。with与run的区别也仅仅是with调用的时候必须要传入一个参数。你可以尝试将run这个改为与这个一样的效果,至于with这个要是层级少还行,要是太多形成地狱嵌套,那就自求多福吧。当然,要是你的目的本来就是不希望人家轻易的读懂代码,这好像也不失为一种方式。
5、also
also函数和let函数功能类型,also也是把接收者作为值参传递给lambda。但有一点不一样的是,also返回接收者对象,而let是返回lambda的结果。因此,also尤其适合针对同一对象进行各项操作然后返回该对象。与Java的链式调用蛮像。
fun alsoFun(){
val person = Person("Jack",18)
val result = person.also {
it.age = 20
}.also {
it.name = "Jacky"
}
println(result)
}
//执行结果
Person(name=Jacky, age=20)
6、takeIf
takeIf函数需要判断lambda提供的条件表达式,给出true或false的结果。如果为true,则从takeIf返回接收者对象,如果为false,则返回null。使用场景为先判断某个条件是否满足,然后在进行相关操作。其实takeIf与if语句非常相似,它的优势是可以直接在对象实例上进行调用,避免了临时变量的赋值操作。
fun takeIfFun(){
val person = Person("Jack",18)
println(person)
val result = person.takeIf {
it.age >= 18
}?.also {
it.name = "Jacky"
}
println(result)
}
//执行结果
Person(name=Jack, age=18)
Person(name=Jacky, age=18)
7、takeUnless
takeUnless是takeIf函数的辅助函数,只有判断你给定的条件结果为false时,takeUnless才会返回原始接收者对象
fun takeUnlessFun(){
val person = Person("Jack",18)
println(person)
val result = person.takeUnless {
it.age >= 18
}
println(result)
}
//执行结果
Person(name=Jack, age=18)
null
ok,字符串、数字操作这块还好。在标准函数这块虽然简单,但只有在实际使用中才能熟悉和灵活运用了,但这些函数提供了各种的操作来丰富我们的处理逻辑以及可以简化我们的代码。点个赞!