kotlin语言提供了一系列功能丰富的运算符,这些运算符包括所有的算术运算符,还包括比较运算符、逻辑运算符、区间运算符和位运算符。kotlin基本支持java的全部运算符(可能在写法上有不同),kotlin不支持三目运算符(因为kotlin可用if表达式来代替三目运算符)
kotlin的很多运算符其实等价于operator修饰的、特定函数名的函数。同时也可以作用于自定义的类,只要提供operator修饰的、特定函数名的函数即可
public operator fun plus(other: Any?): String
# 这个是+号。使用operator修饰
与java相同的运算符
- java支持的运算符包括算术运算符、赋值运算符、扩展后的赋值运算符、比较运算符、逻辑运算符,kotlin也完全支持这些运算符
- kotlin不支持三目运算符,kotlin使用if表达式来代替三目运算符
- kotlin的位运算与java的位运算也略有区别
- 注意:kotlin的运算符都是以方法形式来实现的,这些运算符都具有特定的符号(如+或者-)和固定的优先级
单目前缀运算符
运算符 |
对应的方法 |
+a |
a.unaryPlus() |
-a |
a.unaryMinus() |
!a |
a.not() |
fun unaryOperator(){
val a: Int = 20
val b = +a
val b1 = a.unaryPlus()
println("b: $b --> $a, b1: $b1 --> $a")
val c = -a
val c1 = a.unaryMinus()
println("c: $c --> $a, c1: $c1 --> $a")
val bool: Boolean = false
val bool1 = !false
val bool2 = bool.not()
println("bool1: $bool1, bool2: $bool2")
}
# b: 20 --> 20, b1: 20 --> 20
# c: -20 --> 20, c1: -20 --> 20
# bool1: true, bool2: true
自加和自减运算符
运算符 |
对应的方法 |
a++ |
a.inc() |
a– |
a.dec() |
fun selfAddAndDec(){
var a: Int = 10
println(a++)
println(a)
println(++a)
println(a)
println(a--)
println(a)
println(--a)
println(a)
}
# 10
# 11
# 12
# 12
# 12
# 11
# 10
# 10
- (++a或者–a),这种是先进行自增或自减,然后赋值
- (a++或者a–),这种是先赋值,然后自增或自减
双目运算符
表达式 |
对应方法 |
a + b |
a.plus(b) |
a - b |
a.minus(b) |
a * b |
a.times(b) |
a / b |
a.div(b) |
a % b |
a.rem(b) |
a…b |
a.rangeTo(b) |
fun doubleOperator(){
val a: Int = 12
val b: Int = 5
println(a + b)
println(a.plus(b))
println(a - b)
println(a.minus(b))
println(a * b)
println(a.times(b))
println(a / b)
println(a.div(b))
println(a % b)
println(a.rem(b))
//表示范围
println(b .. a)
println(b.rangeTo(a))
}
# 17
# 17
# 7
# 7
# 60
# 60
# 2
# 2
# 2
# 2
# 5..12
# 5..12
in 和 !in
运算符 |
对应方法 |
a in b |
b.contains(a) |
a !in b |
!b.minus(a) |
fun inAndNotIn(){
val a: String = "Sun Tiancai"
val b: Array = arrayOf("12", "23", "45")
println("Sun" in a)
println("23" in b)
println(b.contains("23"))
println(a.contains("Sun"))
println("cao" !in a)
}
# true
# true
# true
# true
# true
索引访问运算符
运算符 |
对应方法 |
a[i] |
a.get(i) |
a[i, j] |
a.get(i, j) |
a[n_1, n_2, n_3…n_n] |
a.get(n_1, n_2, …, n_n) |
a[i] = b |
a.set(b) |
a[i, j] = b |
a.set(i, j, b) |
a[n_1, n_2, … , n_n] = b |
a.set(n_1, n_2, … , n_n, b) |
fun indexOperator(){
val a: String = "fkKotlin"
println(a[2])
println(a.get(2))
val arr = java.util.ArrayList()
arr.add("zhang")
arr.add(1, "san")
println(arr.get(0))
println(arr[1])
}
# K
# K
# zhang
# san
调用运算符
运算符 |
对应方法 |
a() |
a.invoke() |
a(b) |
a.invoke(b) |
a(a, b, … , c, d) |
a.invoke(a, b, … , c, d) |
fun getInvoke(){
val s = "java.lang.String"
//使用反射获取String类的lenght
val mtd = Class.forName(s).getMethod("length")
//使用传统方法来获取
println(mtd.invoke("java"))
//使用调用运算符
println(mtd("java"))
}
# 4
# 4
广义赋值运算符
- a += b这种的
- 这种广义运算符有一点特殊,比如a += b, 实际上相当于a = a + b, 因此在程序中进行a += b运算时,往往并不需要a有plusAssign()方法
- 对于广义赋值操作,例如a += b,编译器会先判断plusAssign()方法是否存在,如果存在,则执行以下步骤:
- 如果plus()方法也存在,kotlin将会报错(调用目标方法不明确)
- 确保plusAssign()没有返回值,否则报错
- 如果能通过前两步的检查,则转换为执行a.plusAssign(b).
- 如果plusAssign方法不存在,那么a += b 将转换为a = a + b 代码
相等与不相等运算符
运算符 |
对应方法 |
a == b |
a?.equal(b) ?: (b === null) |
a != b |
!(a?.equal(b)) ?: (b === null) |
fun equal(){
val a = java.lang.String("java")
val b = java.lang.String("kotlin")
val c = java.lang.String("kotlin")
println(b == c)
println(a.equals(c))
println(a != b)
}
# true
# false
# true
比较运算符
运算符 |
对应方法 |
a > b |
a.compareTo(b) > 0 |
a < b |
a.compareTo(b) < 0 |
a >= b |
a.compareTo(b) >= 0 |
a <= b |
a.compareTo(b) <= 0 |
fun compareToUse(){
val a = "java"
val b = "kotlin"
println('j'.toInt())
println('k'.toInt())
println(a > b)
println(a.compareTo(b) > 0)
val d1 = java.util.Date()
val d2 = java.util.Date(System.currentTimeMillis() - 1000)
println(d1 > d2)
println(d1.compareTo(d2) > 0)
}
# 106
# 107
# false
# false
# true
# true
位运算
- 虽然kotlin也提供了与java功能完全相同的位运算,但是这些位运算符都不是以特殊符给出的吗,而是infix函数的形式给出的
- kotlin支持的位运算同样也有7中
操作符 |
含义 |
描述 |
and(bits) |
按位与 |
当两位同时为1时才返回1 |
or(bits) |
按位或 |
当两位有一个为1时就返回1 |
inv(bits) |
按位非 |
单目运算符,将操作数取反 |
xor(bits) |
按位异或 |
当两位不同时,返回1 |
shl(bits) |
按位左移 |
左移运算符 |
shr(bits) |
按位右移 |
右移运算符 |
ushr(bits) |
无符号按位右移 |
无符号右移运算符 |
- kotlin中的位运算只对Int和Long类型有效
第一个运算数 |
第二个运算数 |
按位与 |
按位或 |
按位异或 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
//按位与
fun bitsAnd(){
println(9 and 5)
/*
9的二进制为00001001
5的二进制为00000101
按位与and 当两个同位的数都是1,才返回1
即 9 and 5 得到的二进制数为00000001 即1
*/
}
# 1
//按位或
fun bitsOr(){
println(9 or 5)
/*
9的二进制为00001001
5的二进制为00000101
按位或 or 当两个同位的数有一个数为1时返回1
即 9 or 5 得到的二进制为 00001101 即13
*/
}
# 13
//按位异或
fun bitsXor(){
println(9 xor 5)
/*
9的二进制为00001001
5的二进制为00000101
按位异或 xor 当两个同位的数不相同时返回1
即 9 xor 5 得到的二进制为00001100 即12
*/
}
区间运算符
- kotlin提供了两个区间运算符,即闭区间运算符和半开区间运算符,都是比较方便的构建一种数据结构,这种数据结构可包含区间内的所有值
闭区间运算符
- 闭区间运算符a … b用于定义一个从a~b的所有值得区间。杜宇闭区间而言,a是不可以大于b的,否则就会报错
- a … b 区间,a和b的值相等的时候,返回一个值
fun intervalClose(){
val arr = 1 .. 5
for (it in arr){
println(it)
}
println("")
val arr1 = 1 ..1
for (it in arr1){
println(it)
}
}
# 1
# 2
# 3
# 4
# 5
# 1
半开区间运算符 until被infix修饰
- a until b,定义一个从a到b的区间,包含a,但不包含b。并且a必须大于b
- 当a和b一样时,返回空区间
fun OCInterval(){
val arr = 1 until 5
for (it in arr){
println(it)
}
println("-----------------")
val arr1: Array = arrayOf(1, 2, 3, 4, 5, 6)
for (it in arr1.indices){
println("$it value ${arr1[it]}")
}
println("*******************")
for (it in 0 until arr1.size){
println("$it value ${arr1[it]}")
}
}
# 1
2
3
4
-----------------
0 value 1
1 value 2
2 value 3
3 value 4
4 value 5
5 value 6
*******************
0 value 1
1 value 2
2 value 3
3 value 4
4 value 5
5 value 6
反向区间,downTown被infix修饰
fun downToInterval(){
val arr = 5 downTo 1
for (it in arr){
println(it)
}
}
# 5
4
3
2
1
区间步长
fun intervalStep(){
val arr1 = 1 .. 5 step 2
for (it in arr1){
println(it)
}
println("------------------------")
val arr2 = 1 until 5 step 2
for (it in arr2){
println(it)
}
println("***********************")
val arr3 = 5 downTo 1 step 2
for (it in arr3){
println(it)
}
}
# 1
3
5
------------------------
1
3
***********************
5
3
1
运算符重载
- kotlin的运算符都是靠特定名称的方法支撑的,因此只要重载这些名称的方法,我们就可以为任意类添加这些运算符
- 重载运算符的方法需要用operator来修饰
重载单目前缀运算符
- +(unaryPlus())-(unaryMinus) !(not)
data class Data(val x: Int, val y: Int){
operator fun unaryMinus(): Data{
return Data(-x, -y)
}
}
operator fun Data.not(): Data{
return Data(-x, -y)
}
fun main(){
val d = Data(4, 10)
println(-d)
println(!d)
}
# Data(x=-4, y=-10)
# Data(x=-4, y=-10)
重载自加和自减运算符
- ++(inc()) --(dec()) 并以operator修饰
data class Data(val x: Int, val y: Int){
operator fun unaryMinus(): Data{
return Data(-x, -y)
}
//为Data类定义一个inc()fangfa
operator fun inc(): Data{
return Data(x + 1, y + 1)
}
}
operator fun Data.not(): Data{
return Data(-x, -y)
}
//以扩展的形式为Data类添加dec方法
operator fun Data.dec(): Data{
return Data(x - 1, y - 1)
}
fun main(){
var d = Data(4, 10)
println(++d)
println(d)
println(--d)
println(d)
}
# Data(x=5, y=11)
Data(x=5, y=11)
Data(x=4, y=10)
Data(x=4, y=10)