我非常喜欢groovy中的in
运算符。但现在我发现了一个奇怪的行为
请参阅以下脚本。
int x = 1
long y = 1
println "x == y " + (x == y) // true
println "x == new Long(y) " + (x == new Long(y)) // true
println "x in [y] " + (x in [y]) // false Why?
println "[y].contains(x) " + [y].contains(x) // false Why?
in
运算符或contains()
返回false
,尽管两个数字相等。但为什么?
我了解到集合不能包含原始类型,但x == new Long(y)
是真的。
答案 0 :(得分:3)
为什么不能正常工作?
因为x
是int
而y
是long
。
为什么(x == y)返回true?
==
运算符使用后面的类型转换,因此(x == y)
与:
(x == (int)y)
使用[]
语法在groovy中创建列表时,groovy使用后面的ArrayList
类。因此,in
和contains()
方法返回取决于contains()
方法实现:
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
您可以看到它调用indexOf
方法:
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
并且indexOf
方法实际上取决于传递的对象的equals方法实现。
因此,当您说[y].contains(x)
或x in [y]
时,它会使用Integer
的{{1}}方法实现:
equals()
正如您所看到的,如果您没有传递public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
而不管实际值如何,它将返回false
。
如果说int
或[x].contains(y)
它将使用y in [x]
的等于方法实现:
Long
如果参数不是public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
的实例,则无论值是多少,都会再次返回false
。
作为进一步示例,此代码应返回false:
long