基元类型和IN运算符

时间:2017-04-19 08:27:20

标签: groovy collections

我非常喜欢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)是真的。

1 个答案:

答案 0 :(得分:3)

为什么不能正常工作?
因为xintylong

为什么(x == y)返回true?
==运算符使用后面的类型转换,因此(x == y)与:

相同
(x == (int)y)

使用[]语法在groovy中创建列表时,groovy使用后面的ArrayList类。因此,incontains()方法返回取决于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