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

By using java reflection, we can easily know if an object is an array. What's the easiest way to tell if an object is a collection(Set,List,Map,Vector...)?

This question is related to java

The answer is


Java conveniently has the instanceof operator (JLS 15.20.2) to test if a given object is of a given type.

 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
 }

One thing should be mentioned here: it's important in these kinds of constructs to check in the right order. You will find that if you had swapped the order of the check in the above snippet, the code will still compile, but it will no longer work. That is the following code doesn't work:

 // 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
 }

The problem is that a List<?> is-a Collection<?>, so it will pass the first test, and the else means that it will never reach the second test. You have to test from the most specific to the most general type.


Update: there are two possible scenarios here:

  1. You are determining if an object is a collection;

  2. You are determining if a class is a collection.

The solutions are slightly different but the principles are the same. You also need to define what exactly constitutes a "collection". Implementing either Collection or Map will cover the Java Collections.

Solution 1:

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

Solution 2:

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

(1) can also be implemented in terms of (2):

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

I don't think the efficiency of either method will be greatly different from the other.


Test if the object implements either java.util.Collection or java.util.Map. (Map has to be tested separately because it isn't a sub-interface of Collection.)


Since you mentioned reflection in your question;

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

Have you thinked about using instanceof ? Like, say

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

Although not that pure OOP style, it is however largely used for so-called "type escalation".