3.1.4 in和!in运算符
in和!in对应的固定方法名字依次如表3.4所示。
表3.4 in和!in运算符
运算符 对应的方法
a in b b.contains(a)
a !in b !b.minus(a)
例如如下程序:
程序清单:codes\03\3.1\InTest.kt
fun main(args: Array<String>) {
var str = "fkjava.org"
// 调用String的contains方法判断
println( str.contains("java") )
// 使用in运算符判断
println("java" in str)
val array = arrayOf(24, 45, 100, -3, 30)
// 调用Array的contains方法判断
println(array.contains(100)) // 输出true
// 使用in运算符判断
println(100 in array) // 输出true
}
上面代码可以看出,由于String类中存在带一个参数的contains()方法,在Kotlin中即可使用in运算符进行计算。由此可见,以后读者在查阅API时发现某个类有带一个参数的contains()方法,那就说明可对该类的实例使用in、!in运算符。
提示:这就是Kotlin比Java简洁的地方,Java程序要判断某个String是否包含某个子串,只能调用contains()方法进行判断,但Kotlin则只要使用in运算符即可搞定。Kotlin提供了大量这种“语法糖”来让开发者能享受编程。
3.1.5 索引访问运算符
索引访问运算符对应的固定方法名依次如表3.5所示。
表3.5 索引访问运算符
运算符 对应的方法
a[i] a.get(i)
a[i , j] a.get(i, j)
a[i_1 ,... i_n] a.get(i_1,..., i_n)
a[i] = b a.set(i, b)
a[i , j] = b a.set(i, j, b)
a[i_1 ,... i_n] = b a.set(i_1,..., i_n, b)
例如如下程序:
程序清单:codes\03\3.1\IndexTest.kt
fun main(args: Array<String>) {
var str = "fkjava.org"
// 根据get方法获取指定索引的字符
println(str.get(2))
// 使用索引运算符来获取指定索引的字符
println(str[2])
// 创建Java的ArrayList集合
var list = java.util.ArrayList<String>()
list.add("Java")
list.add("Kotlin")
list.add("Go")
// 使用索引运算符来获取指定索引的List集合元素
println(list[1]) // 输出Kotlin
// 使用索引运算符来修改指定索引的List集合元素
list[2] = "Swift"
println(list)
}
从上面粗体字代码可以看出,由于String类提供了get(index)方法,因此程序即可通过str[2]这样的索引运算符来获取指定索引的字符;而Java的ArrayList则提供了get(index)和set(index, val)方法,因此程序可通过索引运算符获取或修改指定索引处的集合元素。
提示:这其实也是Kotlin的语法糖。
3.1.6 调用运算符
调用运算符对应的固定方法名依次如表3.6所示。
表3.6 调用运算符
运算符 对应的方法
a() a.invoke()
a(b) a.invoke(b)
a(b1, b2) a.invoke(b1, b2)
a(b1, b2, b3, ...) a.invoke(b1, b2, b3, ...)
从上面可以看出,调用运算符其实就是可以省略invoke方法名。例如如下程序:
程序清单:codes\03\3.1\InvokeTest.kt
fun main(args: Array<String>) {
val s = "java.lang.String"
// 使用反射获取String类的length()方法
val mtd = Class.forName(s).getMethod("length")
// 使用传统方法,使用Method对象的invoke()方法
println(mtd.invoke("java")) // 输出4
// 使用调用运算符
println(mtd("java") // 输出4
}
上面两行粗体字代码的本质是一样的,由于Method类提供了invoke()方法,因此程序即可按传统Java方式调用invoke()方法,也可直接使用调用运算符进行调用。
3.1.7 广义赋值
广义赋值运算符对应的固定方法名依次如表3.7所示。
表3.7广义赋值运算符
运算符 对应的方法
a += b a.plusAssign(b)
a -= b a.minusAssign(b)
a *= b a timesAssign(b)
a /= b a.divAssign(b)
a %= b a.remAssign(b)
这种广义的赋值运算符有些特殊,比如a += b,实际上相当于a = a + b,因此程序中使用a += b运算时,往往并不需要a有plusAssign()方法。
对于a += b表达式,Kotlin实际执行过程如下。
对于广义赋值操作,例如 a += b,编译器会先判断plusAssign()方法是否存在,如果该方法存在则按如下步骤执行。
(1)如果plus()方法也存在,Kotlin将会报告错误(调用的目标方法不确定)。
(2)确保plusAssign没有返回值,否则报告错误。
注意:Kotlin的赋值运算不是表达式,因此不需要返回值。
(3)如果能通过前2步的检查,转换为执行a.plusAssign(b)。
如果a变量的plusAssign()方法不存在,a += b将转化为a = a + b 代码。
3.1.8 相等与不等运算符
==和!=对应的固定方法名依次如表3.8所示。
表3.8 相等和不等运算符
运算符 对应的方法
a == b a?.equals(b) ?: (b === null)
a != b !(a?.equals(b) ?: (b === null)))
从上面介绍可以看出,Kotlin的==不再比较两个变量是否引用同一个对象。实际上==与equals()比较基本是等义的,只不过==比较起来是空指针安全的。例如如下程序。
程序清单:codes\03\3.1\EqualsTest.kt
fun main(args: Array<String>) {
var s1 = java.lang.String("java")
var s2 = java.lang.String("java")
println(s1 == s2); // 输出true
println(s1.equals(s2)); // 输出true
}
上面两行粗体字代码的本质是一样的,因此虽然s1、s2两个变量指向两个不同的字符串,但上面两行粗体字代码依然会输出true。
Java提供的==和!=在Kotlin则改为由===和!==代替了,如下代码将会输出false。
println(s1 === s2); // 输出false
上面s1 === s2判断时才要求s1、s2两个变量指向同一个对象。
3.1.9 比较运算符
比较运算符对应的固定方法名依次如表3.9所示。
表3.9 比较运算符
运算符 对应的方法
a > b a.compareTo(b) > 0
a < b a.compareTo(b) < 0
a >= b a.compareTo(b) >= 0
a <= b a.compareTo(b) <= 0
从上面介绍可以看出,比较运算符其实就是由compareTo()方法来实现的,而该方法是Comparable接口中定义的方法,因此原来Java类中支持使用compareTo()方法比较大小的对象,都可使用比较运算符进行计算。例如如下代码。
程序清单:codes\03\3.1\CompareTest.kt
fun main(args: Array<String>) {
var s1 = "java"
var s2 = "kotlin"
// 下面两行代码是相同的
println(s1 > s2) // 输出false
println(s1.compareTo(s2) > 0) // 输出false
var date1 = java.util.Date()
var date2 = java.util.Date(System.currentTimeMillis() - 1000)
println(date1 > date2) // 输出true
println(date1.compareTo(date2) > 0) // 输出true
}
上面程序中使用比较运算符对String、Date两个类的实例进行大小比较,由于这两个类都实现了Comparable接口,因此完全可以使用比较运算符来比较大小(至于各种数值类型,就更可以比较大小),Kotlin将会把大小比较运算符转换为通过compareTo()方法进行比较。
提示:String比较大小的规则是按字符的字符编号大小进行比较——先比较两个字符串的首字母;如果首字母相同,再比较第二个字母……以此类推,这其实是Java的知识。
由此可见,使用Kotlin编程时,只要某个类实现Comparable接口,那么该类的实例即可使用大小比较运算符来比较大小。
以上内容节选自《疯狂Kotlin讲义》:一本让您最直接认识Kotlin的疯狂讲义
往期连载
in和!in对应的固定方法名字依次如表3.4所示。
表3.4 in和!in运算符
运算符 对应的方法
a in b b.contains(a)
a !in b !b.minus(a)
例如如下程序:
程序清单:codes\03\3.1\InTest.kt
fun main(args: Array<String>) {
var str = "fkjava.org"
// 调用String的contains方法判断
println( str.contains("java") )
// 使用in运算符判断
println("java" in str)
val array = arrayOf(24, 45, 100, -3, 30)
// 调用Array的contains方法判断
println(array.contains(100)) // 输出true
// 使用in运算符判断
println(100 in array) // 输出true
}
上面代码可以看出,由于String类中存在带一个参数的contains()方法,在Kotlin中即可使用in运算符进行计算。由此可见,以后读者在查阅API时发现某个类有带一个参数的contains()方法,那就说明可对该类的实例使用in、!in运算符。
提示:这就是Kotlin比Java简洁的地方,Java程序要判断某个String是否包含某个子串,只能调用contains()方法进行判断,但Kotlin则只要使用in运算符即可搞定。Kotlin提供了大量这种“语法糖”来让开发者能享受编程。
3.1.5 索引访问运算符
索引访问运算符对应的固定方法名依次如表3.5所示。
表3.5 索引访问运算符
运算符 对应的方法
a[i] a.get(i)
a[i , j] a.get(i, j)
a[i_1 ,... i_n] a.get(i_1,..., i_n)
a[i] = b a.set(i, b)
a[i , j] = b a.set(i, j, b)
a[i_1 ,... i_n] = b a.set(i_1,..., i_n, b)
例如如下程序:
程序清单:codes\03\3.1\IndexTest.kt
fun main(args: Array<String>) {
var str = "fkjava.org"
// 根据get方法获取指定索引的字符
println(str.get(2))
// 使用索引运算符来获取指定索引的字符
println(str[2])
// 创建Java的ArrayList集合
var list = java.util.ArrayList<String>()
list.add("Java")
list.add("Kotlin")
list.add("Go")
// 使用索引运算符来获取指定索引的List集合元素
println(list[1]) // 输出Kotlin
// 使用索引运算符来修改指定索引的List集合元素
list[2] = "Swift"
println(list)
}
从上面粗体字代码可以看出,由于String类提供了get(index)方法,因此程序即可通过str[2]这样的索引运算符来获取指定索引的字符;而Java的ArrayList则提供了get(index)和set(index, val)方法,因此程序可通过索引运算符获取或修改指定索引处的集合元素。
提示:这其实也是Kotlin的语法糖。
3.1.6 调用运算符
调用运算符对应的固定方法名依次如表3.6所示。
表3.6 调用运算符
运算符 对应的方法
a() a.invoke()
a(b) a.invoke(b)
a(b1, b2) a.invoke(b1, b2)
a(b1, b2, b3, ...) a.invoke(b1, b2, b3, ...)
从上面可以看出,调用运算符其实就是可以省略invoke方法名。例如如下程序:
程序清单:codes\03\3.1\InvokeTest.kt
fun main(args: Array<String>) {
val s = "java.lang.String"
// 使用反射获取String类的length()方法
val mtd = Class.forName(s).getMethod("length")
// 使用传统方法,使用Method对象的invoke()方法
println(mtd.invoke("java")) // 输出4
// 使用调用运算符
println(mtd("java") // 输出4
}
上面两行粗体字代码的本质是一样的,由于Method类提供了invoke()方法,因此程序即可按传统Java方式调用invoke()方法,也可直接使用调用运算符进行调用。
3.1.7 广义赋值
广义赋值运算符对应的固定方法名依次如表3.7所示。
表3.7广义赋值运算符
运算符 对应的方法
a += b a.plusAssign(b)
a -= b a.minusAssign(b)
a *= b a timesAssign(b)
a /= b a.divAssign(b)
a %= b a.remAssign(b)
这种广义的赋值运算符有些特殊,比如a += b,实际上相当于a = a + b,因此程序中使用a += b运算时,往往并不需要a有plusAssign()方法。
对于a += b表达式,Kotlin实际执行过程如下。
对于广义赋值操作,例如 a += b,编译器会先判断plusAssign()方法是否存在,如果该方法存在则按如下步骤执行。
(1)如果plus()方法也存在,Kotlin将会报告错误(调用的目标方法不确定)。
(2)确保plusAssign没有返回值,否则报告错误。
注意:Kotlin的赋值运算不是表达式,因此不需要返回值。
(3)如果能通过前2步的检查,转换为执行a.plusAssign(b)。
如果a变量的plusAssign()方法不存在,a += b将转化为a = a + b 代码。
3.1.8 相等与不等运算符
==和!=对应的固定方法名依次如表3.8所示。
表3.8 相等和不等运算符
运算符 对应的方法
a == b a?.equals(b) ?: (b === null)
a != b !(a?.equals(b) ?: (b === null)))
从上面介绍可以看出,Kotlin的==不再比较两个变量是否引用同一个对象。实际上==与equals()比较基本是等义的,只不过==比较起来是空指针安全的。例如如下程序。
程序清单:codes\03\3.1\EqualsTest.kt
fun main(args: Array<String>) {
var s1 = java.lang.String("java")
var s2 = java.lang.String("java")
println(s1 == s2); // 输出true
println(s1.equals(s2)); // 输出true
}
上面两行粗体字代码的本质是一样的,因此虽然s1、s2两个变量指向两个不同的字符串,但上面两行粗体字代码依然会输出true。
Java提供的==和!=在Kotlin则改为由===和!==代替了,如下代码将会输出false。
println(s1 === s2); // 输出false
上面s1 === s2判断时才要求s1、s2两个变量指向同一个对象。
3.1.9 比较运算符
比较运算符对应的固定方法名依次如表3.9所示。
表3.9 比较运算符
运算符 对应的方法
a > b a.compareTo(b) > 0
a < b a.compareTo(b) < 0
a >= b a.compareTo(b) >= 0
a <= b a.compareTo(b) <= 0
从上面介绍可以看出,比较运算符其实就是由compareTo()方法来实现的,而该方法是Comparable接口中定义的方法,因此原来Java类中支持使用compareTo()方法比较大小的对象,都可使用比较运算符进行计算。例如如下代码。
程序清单:codes\03\3.1\CompareTest.kt
fun main(args: Array<String>) {
var s1 = "java"
var s2 = "kotlin"
// 下面两行代码是相同的
println(s1 > s2) // 输出false
println(s1.compareTo(s2) > 0) // 输出false
var date1 = java.util.Date()
var date2 = java.util.Date(System.currentTimeMillis() - 1000)
println(date1 > date2) // 输出true
println(date1.compareTo(date2) > 0) // 输出true
}
上面程序中使用比较运算符对String、Date两个类的实例进行大小比较,由于这两个类都实现了Comparable接口,因此完全可以使用比较运算符来比较大小(至于各种数值类型,就更可以比较大小),Kotlin将会把大小比较运算符转换为通过compareTo()方法进行比较。
提示:String比较大小的规则是按字符的字符编号大小进行比较——先比较两个字符串的首字母;如果首字母相同,再比较第二个字母……以此类推,这其实是Java的知识。
由此可见,使用Kotlin编程时,只要某个类实现Comparable接口,那么该类的实例即可使用大小比较运算符来比较大小。
以上内容节选自《疯狂Kotlin讲义》:一本让您最直接认识Kotlin的疯狂讲义
往期连载