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

Posted

技术标签:

【中文标题】如何检查对象是不是是Java中的集合类型?【英文标题】:How to check if an Object is a Collection Type in Java?如何检查对象是否是Java中的集合类型? 【发布时间】:2011-02-08 17:55:31 【问题描述】:

通过使用java反射,我们可以很容易地知道一个对象是否是一个数组。判断一个对象是否为集合(Set、List、Map、Vector...)的最简单方法是什么?

【问题讨论】:

【参考方案1】:
if (x instanceof Collection<?>)


if (x instanceof Map<?,?>)

【讨论】:

请注意其中的?。您无法访问已擦除的组件类型。如果您需要知道集合中可能包含哪些类型的对象,则需要查看元素本身。 在没有元素的情况下,如何找出集合中有哪些对象?【参考方案2】:

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

    您正在确定一个对象是否是一个集合;

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

解决方案略有不同,但原理相同。您还需要定义究竟是什么构成了“集合”。实现 CollectionMap 将涵盖 Java 集合。

解决方案 1:

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

解决方案 2:

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

(1)也可以按照(2)来实现:

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

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

【讨论】:

因为这个任务可以在没有“instanceof”的情况下解决 @den bardmadym 为什么你不想使用 instaceof? 我相信 instanceof 比 isAssignableFrom 更高效,不是吗? 我只会在必要时使用反射(isAssignableFrom),即在编译时不知道要测试的类。否则,一个简单的 instanceof 更容易输入和阅读,恕我直言。 @duduamar 可能你是对的(应该看看字节码)。肯定 isAssignableFrom 的使用不能胜过 instanceof【参考方案3】:

既然你在问题中提到了反思;

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

【讨论】:

最佳答案在这里 IMO 您也可以使用它,如果 myArray 引用为空,您将获得 NPE。因此需要检查 null 作为结果。通过instanceof 进行检查是没有必要的。见***.com/questions/2950319/… @Alexandr:其他答案都没有else 子句或检查null。至少有了这个答案,你不得不考虑 null 选项。 @Foumpie,obj instanceof Collection。我从来没有得到过NPE。我不需要检查空值。如果obj 为空,此语句的结果将为假。通过反射,您无需明确检查即可获得 NPE。【参考方案4】:

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
 

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

 // 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&lt;?&gt;是-aCollection&lt;?&gt;,所以它会通过第一个测试,而else意味着它永远不会达到第二个测试。 你必须从最具体到最一般的类型进行测试

【讨论】:

地图不扩展集合。 @Thilo:脑残;修改为List。重点仍然存在。【参考方案5】:

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

【讨论】:

【参考方案6】:

您是否考虑过使用 @987654321@ ? 比如,说

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

虽然不是那种纯粹的 OOP 风格,但它主要用于所谓的“类型升级”。

【讨论】:

像我这样的老开发人员有时倾向于依赖 java1.5 之前的符号来处理像这样的不可编译示例,尤其是当泛型符号没有增加任何价值时。 增加的价值是您明确声明类型未知。无法以 1.5 之前的符号表示此信息。 @Max 表现得像个复活者?我知道你在搜索什么点 ;-) 无论如何,在 Java 5+ 中,CollectionCollection&lt;?&gt; 是等价的,因为它们都将包含 Object 实例。因此,泛型在这里没有附加价值。

以上是关于如何检查对象是不是是Java中的集合类型?的主要内容,如果未能解决你的问题,请参考以下文章

Java集合有啥用?

面试3——java集合类总结

java集合

java集合详解

使用 Java Regex,如何检查字符串是不是包含集合中的任何单词?

java中的集合有几种