5.1、只读变量和变量和常量
变量表达
var 来表示变量
只读变量
val表示只读变量
只读变量VS常量
常量的意思是:永远不变。
但是请看下面的例子,Test中的b,它会随着Math的值不一样,获取到的b的值是不一样的,它的值是变化的,所以称为只读变量。
class Test {
val b: Int
get() {
return (Math.random() * 1000).toInt()
}
}
常量要求和表示
1、只能修饰基本类型
2、只能定义在全局范围
3、必须立即用字面量初始化
val b = 3
5.2、分支表达式
if - else表达式
var a: Int = 4
var c = if (a == 3) 4 else 5
Log.e("cdx", "c:$c")
when 表达式写法
注意其中的 -> 箭头。类似于Java中的switch - case
when表达式 - 条件转移到分支、简写写法
val a: Any = 4
val c: Any
when {
a is String -> c = a.length
a == 3 -> c = 3
else -> c = 5
}
简化写法
val a: Any = 4
val c = when {
a is String -> a.length
a == 3 -> 3
else -> 5
}
try - catch 表达式
和Java不同的地方:try - catch表达式可以有返回值。
var a = 1
var b = 0
val c = try {
a / b
} catch (e: Exception) {
0
}
5.3、运算符与中缀表达式
运算符网站
https://kotlinlang.org/docs/operator-overloading.html
== 运算符 VS equal
val str1 = "Hello"
val str2 = "World"
// 下面的两种方式是完全等价的
val result1 = (str1 == str2)
var result2 = str1.equals(str2)
+ 运算符 VS plus
val str1 = "a"
val str2 = "b"
// 下面的两种方式是完全等价的
val result1 = (str1 + str2)
var result2 = str1.plus(str2)
Log.e("cdx", result1.toString())
Log.e("cdx", result2.toString())
in 运算符 VS contains
in 运算符 和contains 方法完全一样
var list = listOf(1, 2, 3, 4)
var result = 2 in list
Log.e("cdx", result.toString())
Log.e("cdx", list.contains(2).toString())
[] 运算符 VS get
val map = mapOf("name" to "张三", "age" to 20)
// [] 和 get 的方式完全一样,编译器推荐使用第二种方式
Log.e("cdx", map.get("name").toString())
Log.e("cdx", map["name"].toString())
> VS compareTo
var result1 = 2 > 3
var result2 = 2.compareTo(3) > 0
Log.e("cdx", result1.toString())
Log.e("cdx", result2.toString())
() 与 invoke
表示 执行。
// 定义匿名函数,用变量去接受这个函数
var func = fun() {
Log.e("cdx", "方法执行了")
}
// 第一种调用函数方法
func()
// 第二种调用函数方法
func.invoke()
自定义运算符
第一步:定义运算符,相当于给Complex这个哥么增加了2个标签(比如幽默),比如 + 这个标签,那么两个Complex哥么通过标签就可以相互的认识。
package com.example.kotlindemo
class Complex(var real: Double, var image: Double) {
override fun toString(): String {
return "$real + $image"
}
}
// 自定义操作符
// 相当于给Complex增加了plus操作符的功能,相当于增加了 + 的功能
operator fun Complex.plus(other: Complex): Complex {
return Complex(this.real + other.real, this.image + other.image)
}
// 自定义减的运算符
// 给Complex增加了减的运算符,增加了 - 的功能
operator fun Complex.minus(other: Complex): Complex {
return Complex(this.real - other.real, this.image - other.image)
}
第二步:然后在页面里面去调用
class MainActivity2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
var c1 = Complex(1.0, 2.0)
var c2 = Complex(3.0, 2.0)
//
var result1 = c1 + c2
Log.e("cdx", result1.toString())
var result2 = c1 - c2
Log.e("cdx", result2.toString())
}
}
中缀表达式-infix的介绍
Kotlin允许在不使用括号和点号的情况下调用函数,那么这种函数被称为 infix函数。
中缀表达式要求和使用
1、只有一个参数。
2、增加infix参数,表示可以省略括号和点号。
class MainActivity2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
2.to(3)
2 to 3
}
// infix:中缀表达式的的标识
// A,B 都是泛型
infix fun <A, B> A.to(b: B): Pair<A, B> {
return Pair(this, b)
}
}
5.4、Lambda表达式
匿名函数的传递
// func:是变量名
// 匿名函数赋值给了一个变量
var func = fun() {
Log.e("cdx", "test")
}
匿名函数的调用
// func:是变量名
// 匿名函数赋值给了一个变量
var func = fun() {
Log.e("cdx", "test")
}
// 通过()运算符去执行
func()
// 通过invoke()去执行
func.invoke()
Lambda表达式的类型
Lambda表达式就是匿名函数的简化。
// 没有参数的Lambda表达式
// 注意func1的类型 () -> Int
var func1: () -> Int = {
Log.e("cdx", "test")
}
// 有参数的Lambda表达式
// 注意func2的类型 (Int, Int) -> Int
var func2: (Int, Int) -> Int = { p1: Int, p2: Int ->
Log.e("cdx", "test,$p1 $p2")
}
Lambda表达式返回值
是由Lambda中的最后一行的语句决定。
5.5、为Person实现equals 和hashCode
package com.example.kotlindemo
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
class MainActivity2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
val hashSet = HashSet<Person>()
hashSet.add(Person("张三", 15))
hashSet.add(Person("张三", 15))
Log.e("cdx", hashSet.size.toString())
}
}
class Person(var name: String, var age: Int) {
override fun equals(other: Any?): Boolean {
Log.e("cdx", "equals")
val person = (other as? Person) ?: return false
return person.name == name && person.age == age
}
override fun hashCode(): Int {
Log.e("cdx", "hashCode")
return name.hashCode() * 7 + age * 5;
}
}
5.6、为String实现四则运算
需要实现下面的效果,实现字符串的加减乘除。
分析:
1、没有办法修改String的源码,所以我们需要使用扩展方法。
2、借助于自定义运算符。
package com.example.kotlindemo
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import java.lang.StringBuilder
class MainActivity2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
val str: String = "HelloWorld"
val result = str - "World"
Log.e("cdx", result)
val result2 = str * 5
Log.e("cdx", result2)
val result3 = str / "l"
Log.e("cdx", result3.toString())
}
}
operator fun String.minus(other: Any): String {
return this.replaceFirst(other.toString(), "")
}
operator fun String.times(time: Int): String {
var sb = StringBuilder()
for (i in 0 until time) {
sb.append(this)
}
return sb.toString()
}
operator fun String.div(str: String): Int {
// 这个东西很好玩
// String字符串上一点一点的划,划的长度是str.lenght,
然后间隔是1,表示一个一个的划
// 然后获取到划到的集合
return this.windowed(str.length, 1) {
it == str
}
// 然后数一数里面欧多少个满足条件的,it为true的就筛选出来
.count {
it
}
}