在许多语言中,使用==
来判断两个值是否相等。有些语言中还有is
,但是意义各不相同,本文着重于介绍各语言中这些概念。
Python
双等号
Python 中的==
来比较两个值是否相等。例如:
a = 5
b = 5
print(a == b) # True
数值上的相等是显而易见的,那么对于对象呢?
先以 Python 自带的 list 对象为例:
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True
Python 将会对 list 中的每个元素进行比较。对于类的实例,实际上是调用__eq__()
方法来进行比较的。
class DemoClass():
def __init__(self, value):
self.value = value
def __eq__(self, other):
return self.value == other.value
instance_a = DemoClass(5)
instance_b = DemoClass(5)
print(instance_a == instance_b) # True
is
Python 中的 is
则表示是否是同一对象:
对于简单的数字:
a = 5
b = 5
print(a is b) # True
但是对于对象:
a = [1, 2, 3]
b = [1, 2, 3]
print(a is b) # Flase
c = a
print(a is c) # True
其它
Python 中还有 isinstance()
函数和 type()
函数,用以确定对象的类别。
区别:
-
type()
不会认为子类是一种父类类型,不考虑继承关系。 -
isinstance()
会认为子类是一种父类类型,考虑继承关系。
如果要判断两个类型是否相同推荐使用 isinstance()。
下面引用菜鸟教程的例子:
class A:
pass
class B(A):
pass
isinstance(A(), A) # True
type(A()) == A # True
isinstance(B(), A) # True
type(B()) == A # False
Java
在上文的 Python 中,==
用来判断值是否相等,is
用来判断是否是同一个对象。而在 Java 中,==
同时拥有以上两种含义。
双等号
==
对于基本数据类型,是比较值;对于引用数据类型,是比较是否是同一对象,或者说是比较堆内存地址。
对于基本类型,自然可以直接==
。(但是 Java 是区分 int 和 Integer,double 和 Double 等的,要注意!)
public static void main(String[] args) {
int a = 5;
int b = 5;
System.out.println(a == b); // true
}
对于类的实例,则比较的是否是同一对象。
class DemoClass {
private final int value;
public DemoClass(int value) {
this.value = value;
}
}
public class Main {
public static void main(String[] args) {
DemoClass instanceA = new DemoClass(5);
DemoClass instanceB = new DemoClass(5);
System.out.println(instanceA == instanceB); // false
DemoClass instanceC = instanceA;
System.out.println(instanceA == instanceC); // true
}
}
equals()
默认情况下,比较是否是同一对象,将上例中的instanceA == instanceB
改为instanceA.equals(instanceB)
,仍然输出false
。
class DemoClass {
private final int value;
public DemoClass(int value) {
this.value = value;
}
}
public class Main {
public static void main(String[] args) {
DemoClass instanceA = new DemoClass(5);
DemoClass instanceB = new DemoClass(5);
System.out.println(instanceA.equals(instanceB)); // false
}
}
因此,我们需要重写(Override)equals()
方法,来实现自定义的比较:
class DemoClass {
private final int value;
public DemoClass(int value) {
this.value = value;
}
@Override
public boolean equals(Object object) {
return this.value == ((DemoClass) object).value;
}
}
public class Main {
public static void main(String[] args) {
DemoClass instanceA = new DemoClass(5);
DemoClass instanceB = new DemoClass(5);
System.out.println(instanceA.equals(instanceB)); // true
}
}
不过上文这种重写并不优雅,工程中请勿这样使用。
instanceof
Java 中使用instanceof
来比较一个对象是否是一个类的实例。
DemoClass
类定义如前文,不赘述。
public static void main(String[] args) {
DemoClass instanceA = new DemoClass(5);
System.out.println(instanceA instanceof DemoClass); // true
}
我们把instanceA
的静态类型从DemoClass
改为Object
,众所周知,DemoClass
继承于Object
。
public static void main(String[] args) {
Object instanceA = new DemoClass(5);
System.out.println(instanceA instanceof DemoClass); // true
}
但是这样输出的仍然是true
。
Kotlin
双等号
首先是对于简单的数字,这种情况下,各语言的==
都会是比较值的。
fun main() {
val a = 5
val b = 5
print(a == b) // true
}
Kotlin 的双等于号相当于 Java 的equals
,这在比较两个字符串是否内容相同时很方便。
在没有重写equals
方法的情况:
class DemoClass(private val value: Int)
fun main() {
val instanceA = DemoClass(5)
val instanceB = DemoClass(5)
println(instanceA == instanceB) // true
val instanceC = instanceA
println(instanceA == instanceC) // true
}
似乎是 Kotlin 会自动生成一个euqals
方法,所以这里的instanceA == instanceB
为true
。
重写了之后,就更加明了了。
class DemoClass(private val value: Int) {
override fun equals(other: Any?): Boolean {
return value == (other as DemoClass?)!!.value
}
}
fun main() {
val instanceA = DemoClass(5)
val instanceB = DemoClass(5)
println(instanceA == instanceB) // true
val instanceC = instanceA
println(instanceA == instanceC) // true
}
三等号
Kotlin 中有三等号===
来判断是否是同一对象。
class DemoClass(private val value: Int) {
override fun equals(other: Any?): Boolean {
return value == (other as DemoClass?)!!.value
}
}
fun main() {
val instanceA = DemoClass(5)
val instanceB = DemoClass(5)
println(instanceA === instanceB) // false
val instanceC = instanceA
println(instanceA === instanceC) // true
}
这里可以看出,instanceA == instanceB
为false
,因为二者并非同一对象。
is
Kotlin 中的 is
类似于 Python 中的 isinstance
、Java 中的instanceof
:
fun main() {
val instanceA = DemoClass(5)
println(instanceA is DemoClass) // true
println(instanceA is Any) // true
}
网友评论