简体   繁体   English

如何检查Object是否是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. 通过使用java反射,我们可以很容易地知道对象是否是一个数组。 What's the easiest way to tell if an object is a collection(Set,List,Map,Vector...)? 什么是判断对象是否是集合的最简单方法(Set,List,Map,Vector ...)?

if (x instanceof Collection<?>){
}

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

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. 实现CollectionMap将涵盖Java Collections。

Solution 1: 解决方案1:

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

Solution 2: 解决方案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): (1)也可以用(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. 我不认为任何一种方法的效率都会与另一种方法大不相同。

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());

Java conveniently has the instanceof operator ( JLS 15.20.2 ) to test if a given object is of a given type. Java方便地使用instanceof运算符( JLS 15.20.2 )来测试给定对象是否属于给定类型。

 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. 问题是List<?>是一个Collection<?> ,所以它将通过第一个测试,而else意味着它永远不会到达第二个测试。 You have to test from the most specific to the most general type . 您必须从最具体到最一般的类型进行测试

Test if the object implements either java.util.Collection or java.util.Map . 测试对象是否实现了java.util.Collectionjava.util.Map ( Map has to be tested separately because it isn't a sub-interface of Collection .) Map必须单独测试,因为它不是Collection的子接口。)

Have you thinked about using instanceof ? 你有没有想过使用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". 虽然不是那种纯粹的OOP风格,但它主要用于所谓的“类型升级”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM