如何检查对象是否为Java中的集合类型?

How to check if an Object is a Collection Type in Java?

通过使用Java反射,我们可以轻松知道对象是否为数组。 判断对象是否为集合(Set,List,Map,Vector ...)的最简单方法是什么?


1
2
3
4
5
if (x instanceof Collection< ? >){
}

if (x instanceof Map<?,?>){
}


更新:这里有两种可能的情况:

  • 您正在确定对象是否为集合;

  • 您正在确定一个类是否是一个集合。

  • 解决方案略有不同,但原理相同。您还需要定义什么才构成"集合"。实现CollectionMap将涵盖Java集合。

    解决方案1:

    1
    2
    3
    public static boolean isCollection(Object ob) {
      return ob instanceof Collection || ob instanceof Map;
    }

    解决方案2:

    1
    2
    3
    public static boolean isClassCollection(Class c) {
      return Collection.class.isAssignableFrom(c) || Map.class.isAssignableFrom(c);
    }

    (1)也可以根据(2)来实现:

    1
    2
    3
    public static boolean isCollection(Object ob) {
      return ob != null && isClassCollection(ob.getClass());
    }

    我认为这两种方法的效率都不会大大不同。


    既然您在问题中提到反思,

    1
    2
    3
    boolean isArray = myArray.getClass().isArray();
    boolean isCollection = Collection.class.isAssignableFrom(myList.getClass());
    boolean isMap = Map.class.isAssignableFrom(myMap.getClass());


    Java方便地使用instanceof运算符(JLS 15.20.2)来测试给定对象是否为给定类型。

    1
    2
    3
    4
    5
    6
    7
     if (x instanceof List< ? >) {  
        List< ? > list = (List< ? >) x;
        // do something with list
     } else if (x instanceof Collection< ? >) {
        Collection< ? > col = (Collection< ? >) x;
        // do something with col
     }

    这里应该提到一件事:在这种类型的结构中,以正确的顺序进行检查很重要。您会发现,如果您在上面的代码段中交换了检查的顺序,代码仍然可以编译,但是将不再起作用。那是下面的代码不起作用:

    1
    2
    3
    4
    5
    6
    7
    8
     // DOESN'T WORK! Wrong order!
     if (x instanceof Collection< ? >) {
        Collection< ? > col = (Collection< ? >) x;
        // do something with col
     } else if (x instanceof List< ? >) { // this will never be reached!
        List< ? > list = (List< ? >) x;
        // do something with list
     }

    问题是List< ? >是-a Collection< ? >,因此它将通过第一个测试,而else意味着它将永远不会到达第二个测试。您必须测试从最具体到最一般的类型。


    测试对象是否实现java.util.Collectionjava.util.Map。 (由于Map不是Collection的子接口,因此必须单独进行测试。)


    您是否考虑过使用instanceof
    就像说

    1
    2
    if(myObject instanceof Collection) {
         Collection myCollection = (Collection) myObject;

    尽管不是那种纯粹的OOP风格,但是它被广泛用于所谓的"类型升级"。