详解 Kotlin 的 equals() , == 和 ===

416 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第四天,点击查看活动详情

详解 Kotlin 的 equals() , == 和 ===

概括

我们在了解Kotlin中的 equals(), == ===请先了解Java中的equals()==,链接: 面试必问系列之----Java中 == ,equals()和hashCode()的区别

在我们了解equals() , =====需要先了解两个概念结构相等引用相等

Kotlin 中有两种类型的相等性:

  • 结构相等(==!=
  • 引用相等(===!==

结构相等(==!=)

在我们 相等运算符是检查比较的值是否相等的运算符。这类似于 Java 的 equals() 方法,为啥这么说呢,在表达式a == b会被翻译为:

a?.equals(b) ?: (b === null)

这我知道,==a不是null的情况下,则会调用a?.equals(b), ?:有点类似于Java中的三木表达式,稍后会详细解说?:===。这里的equals()方法和Java中一样,在基本数据类型(例如Int)则是对值比较,在引用数据类型的时候则进行的是对象地址进行比较

equals()不太来接可以参考这篇 面试必问系列之----Java中 == ,equals()和hashCode()的区别

学习完结构相等(==!=)那么我们看一下一下的代码在巩固一下

val a = 1
val b = 1
System.out.println(a == b);
输出结果:
true
解析:
因为a,b都是基本数据类型,所以比较的是值

val a = "a"
val b = "a"
System.out.println(a == b);
输出结果:
true
解析:
因为string是重写了equals()方法内部比较的是值

class User(val name:String){}
val zhangsan = User("zhangsan")
val lisi = User("lisi")
val zhangsan2 = zhangsan
System.out.println(zhangsan == lisi);
System.out.println(zhangsan == zhangsan2);
输出结果 :
false
true
解析:
因为User是引用数据类型,所以比较的是地址

?:(Elvis 操作符)

当我们有一个可空的引用b 时,我们可以说“如果b 非空,我使用它;否则使用某个非空的值”:

val l: Int = if (b != null) b.length else -1

除了完整的if表达式,这还可以通过 Elvis 操作符表达,写作?::

val l = b?.length ?: -1

如果?:左侧表达式非空,elvis 操作符就返回其左侧表达式,否则返回右侧表达式。 请注意,当且仅当左侧为空时,才会对右侧表达式求值。

请注意,因为 throwreturnKotlin中都是表达式,所以它们也可以用在 elvis 操作符右侧。这可能会非常方便,例如,检测函数参数:

fun foo(node: Node): String? {
    val parent = node.getParent() ?: return null
    val name = node.getName() ?: throw IllegalArgumentException("name expected")
    // ……
}

那么我们在之前的代码,代码的意思就是如果a不是null则调用equals(Any?)方法,否则也是anull 检测b时候与null引用相等

注意:当与 null 显式比较时完全没必要优化你的代码:a == null 会被自动转换为 a === null

引用相等(===或!===)

引用相等(===或!===)用于比较对象的引用是否指向同一个对象,运行时如果是基本数据类型=== 等价于 ==,但是基本数据类型时,不建议使用===,编译器会标黄警告

概念很简单,我们也来看看代码实现效果


val a = 1
val b = 1
System.out.println(a === b);
输出结果:
true
解析:
因为a,b都是基本书籍类型,所以比较的是值

class User(val name:String){}
val zhangsan = User("zhangsan")
val lisi = User("lisi")
val zhangsan2 = zhangsan
System.out.println(zhangsan === lisi);
System.out.println(zhangsan === zhangsan2);
输出结果 :
false
true
解析:
因为User是引用数据类型,所以比较的是否同一个对象

总结

在kotlin中我们可以这样理解

  • kotlin中==可以理解为Java中 equals()
  • kotlin中的===可以理解为java中的==