函数 .contains() 在 Groovy 中无法按预期方式工作
Posted
技术标签:
【中文标题】函数 .contains() 在 Groovy 中无法按预期方式工作【英文标题】:Function .contains() not working in Groovy on expected way 【发布时间】:2018-10-10 16:12:23 【问题描述】:我正在尝试使用 Groovy 编程语言检查 number 是否是列表的成员。
我有这段代码:
List<Long> list = [1, 2, 3]
Long number = 3
println(list.contains(number))
预期的输出是true
,但我得到的结果是false
。
有人解释一下吗?
【问题讨论】:
你尝试过原始long吗? 我知道如何处理这个问题,但我更感兴趣的是为什么这不起作用。 【参考方案1】:泛型类型参数在运行时不具备。检查这个:
List<Long> list = [1, 2, 3]
list.eachprintln it.getClass()
哪些打印:
class java.lang.Integer
class java.lang.Integer
class java.lang.Integer
真正的混淆是由.equals
和==
实现之间的奇怪行为差异引起的:
Long.valueOf(3).equals(Integer.valueOf(3))
===> false
Long.valueOf(3) == Integer.valueOf(3)
===> true
List.contains
似乎在使用.equals
,它检查参数的类,从而解释了为什么强制元素类型为Long
可以解决问题。
因此,在这种不确定性中,我认为唯一确定的是 Groovy 的 ==
执行执行了最直观和可预测的比较。所以我将检查更改为:
boolean contains = list.grepit == 3L //sets value to true if matches at least 1
当人们不必了解与文字相关的数据类型时,它会有所帮助:
def ints = [1, 2, 3]
def longs = [1L, 2L, 3L]
boolean found1 = ints.grepit == 3L
boolean found2 = ints.grepit == 3
boolean found3 = longs.grepit == 3L
boolean found4 = longs.grepit == 3
println found1
println found2
println found3
println found4
任何人都想要的:
true
true
true
true
【讨论】:
【参考方案2】:您应该为 long 使用特殊的文字值:1L 而不是 1。
List<Long> list = [1L, 2L, 3L]
Long number = 3L
1 是一个整数。 1L很长。
【讨论】:
我明白了,但对我来说很奇怪的是,如果我声明 Long-s 列表,它们将不会被识别为 Long-s 我同意这是出乎意料的(我也来自 Java 背景。)请注意,这将按您的预期工作:list.any(number)
这就是泛型在 JVM 中的实现方式。您可以使用 GroovyConsole 或调试器来检查实际列表。类型为ArrayList
。元素类型的信息丢失。你甚至可以写List<String> list = [1L, 2L, 3L]
,没关系。以上是关于函数 .contains() 在 Groovy 中无法按预期方式工作的主要内容,如果未能解决你的问题,请参考以下文章
GroovyMOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 重写 MetaClass#invokeMethod 方法拦截 JDK 中已经定义的函数 )
错误记录Groovy工程中的文件查找策略 ( main 函数中需要使用 src/main/groovy/Script.groovy | Groovy 脚本直接使用代码相对路径 )
GroovyGroovy 方法调用 ( Groovy 构造函数中为成员赋值 | Groovy 函数的参数传递与键值对参数 | 完整代码示例 )