Reputation: 15917
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...)?
Upvotes: 90
Views: 146759
Reputation: 1555
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());
Upvotes: 41
Reputation: 383726
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.
Upvotes: 10
Reputation: 625037
Update: there are two possible scenarios here:
You are determining if an object is a collection;
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.
Upvotes: 61
Reputation: 137567
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
.)
Upvotes: 3
Reputation: 22292
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".
Upvotes: 1
Reputation: 262474
if (x instanceof Collection<?>){
}
if (x instanceof Map<?,?>){
}
Upvotes: 137