Kotlin运算符和表达式

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的运算符都是以方法形式来实现的,这些运算符都具有特定的符号(如+或者-)和固定的优先级
单目前缀运算符
  • 单目前缀运算符有3个,+、-、!
运算符 对应的方法
+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修饰
  • a downTo b, b不能大于a。闭区间
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)

你可能感兴趣的:(Kotlin)