如何在Groovy中检查对象是否为列表、集合或数组?

39
问题就像标题所说的一样简单。在Groovy中如何检查对象是否为列表、集合或数组?但是我找不到一个简单的方法来检查它。有任何想法吗?

问题就像标题所说的一样简单。在Groovy中如何检查对象是否为列表、集合或数组?但是我找不到一个简单的方法来检查它。您有什么想法吗?

6个回答

45

ListCollection,因此这些检查不是互相排斥的:

def foo = ...
boolean isCollection = foo instanceof Collection
boolean isList = foo instanceof List
boolean isSet = foo instanceof Set
boolean isArray = foo != null && foo.getClass().isArray()

1
这是我在Java中可以做到的方式:)。那么,没有Groovy的方法吗? - Andrey Adamovich
"boolean isArray = foo instanceof Object[]" 也应该可以工作。如果 foo 是 null,它将返回 false 而不会抛出异常。" - John Wagenleitner
4
对于不重复造轮子的做法我表示赞同。在我看来,在这种情况下Java语法相当简洁,比建议的Groovy解决方案更易读。 - peterp
我同意peterp的观点,但我觉得有趣的是Groovy没有提供一种简单的方法来运行这样一个测试(当然,除非它在2018-02-14之后提供了...)。 - mike rodent
FWIW这对于哈希表也完美地起作用:交换两个映射定义并查看:def map = [me: 'you', him: 'her'] // def map = 'just a string' if (map instanceof HashMap) { println 'hash' } else { println 'not hash' } - Max Cascone

42

我不知道你是否需要区分集合(Collection)、列表(List)和数组(Array),或者只是想知道一个对象是否是这些类型中的 任意一种。如果是后者,你可以使用以下方法:

boolean isCollectionOrArray(object) {    
    [Collection, Object[]].any { it.isAssignableFrom(object.getClass()) }
}

// some tests
assert isCollectionOrArray([])
assert isCollectionOrArray([] as Set)
assert isCollectionOrArray([].toArray())
assert !isCollectionOrArray("str")

在Groovy控制台中运行上面的代码以确认其按照宣传的方式运行


7
如果您正在寻找一种Groovy的方式,请查看in操作符。它实际上是Class.isAssignableFrom(Class<?>)Class.isInstance(Object)的组合,这意味着您可以用它来测试类以及对象。
// Test classes
assert ArrayList in Collection
assert ArrayList in List
assert HashSet in Collection
assert HashSet in Set

// Test objects
def list = [] as ArrayList
def set = [] as HashSet

assert list in Collection
assert list in List
assert set in Collection
assert set in Set

测试一个对象是否为数组可能有些棘手。我建议使用@BurtBeckwith的方法。

def array = [].toArray()

assert array.getClass().isArray()

3
我使用这个函数将一个对象转换成数组,如果它已经是一个集合,它将返回一个副本,否则将其包装在列表中。所以在处理时不需要检查它,它总是一个集合。
def arrayfy = {[] + it ?: [it]}
def list = arrayfy(object) // will be always a list

除非我将“object”中的“O”大写,否则会出现错误。 - Josh Graham
1
这里的 object 只是一个变量名,可以是任何名称。 - plajko

1
通常你会想要使用鸭子类型来检查它的行为。
def foo = someMethod()
if (foo.metaClass.respondsTo('each')) {
  foo.each {println it}
}

1
每个字符串都会响应,我认为。 - Andrey Adamovich
1
Groovy在Object中添加了each方法,因此每个对象都可以响应each。因此,这个提案是有问题的。 - Dónal
1
天啊,我没想到 Object 会响应 each。无论如何,你都需要检查你实际要使用的方法,所以如果你使用了不同的方法,这可能还可以正常工作。如果你计划使用 each,那么不幸的是这将不足够。 - Adam Stegman
为什么不直接使用对象的类来确定它的类型,而是检查特定方法的存在呢?我没有看到使用这种方法比instanceof更有益处的地方。 - Dónal
2
鸭子类型的好处在于你不需要硬编码一个特定的实现。调用者可以使用你的文档来决定如果他们喜欢不同的实现(或者自己的实现)。 - Adam Stegman

0
只需使用 instanceof 运算符并检查对象是否是 java.util.Collection 的实例即可。

Burt回答说,没有很好的方法,但我也会尝试对象instanceof Object[]...但我并不确定。 - Simone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接