Как проверить, является ли объект типом коллекции в Java? - PullRequest
61 голосов
/ 16 апреля 2010

Используя отражение Java, мы можем легко узнать, является ли объект массивом. Какой самый простой способ определить, является ли объект коллекцией (Set, List, Map, Vector ...)?

Ответы [ 6 ]

91 голосов
/ 16 апреля 2010
if (x instanceof Collection<?>){
}

if (x instanceof Map<?,?>){
}
43 голосов
/ 16 апреля 2010

Обновление: здесь возможны два сценария:

  1. Вы определяете, является ли объект коллекцией;

  2. Вы определяете, является ли класс коллекцией.

Решения немного отличаются, но принципы одинаковы. Вы также должны определить, что именно представляет собой «коллекция». Реализация Collection или Map покроет Коллекции 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());
}

Не думаю, что эффективность одного из методов будет сильно отличаться от другого.

16 голосов
/ 30 декабря 2015

Поскольку вы упомянули рефлексию в своем вопросе;

boolean isArray = myArray.getClass().isArray();
boolean isCollection = Collection.class.isAssignableFrom(myList.getClass());
boolean isMap = Map.class.isAssignableFrom(myMap.getClass());
6 голосов
/ 16 апреля 2010

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

Здесь следует упомянуть одну вещь: В таких конструкциях важно проверить в правильном порядке . Вы обнаружите, что если вы поменяли порядок проверки в приведенном выше фрагменте, код все равно скомпилируется, но больше не будет работать . То есть следующий код не работает:

 // 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<?> is-a Collection<?>, поэтому он пройдет первый тест, а else означает, что он никогда не достигнет второго теста. Вы должны проверить от самого специфического к наиболее общему типу .

3 голосов
/ 16 апреля 2010

Проверка, реализует ли объект либо java.util.Collection, либо java.util.Map.(Map нужно тестировать отдельно, потому что это не подчиненный интерфейс Collection.)

1 голос
/ 16 апреля 2010

Думали ли вы об использовании <a href="http://mindprod.com/jgloss/instanceof.html" rel="nofollow noreferrer">instanceof</a>? Мол, скажем

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

Хотя это и не тот чистый ООП-стиль, он, тем не менее, широко используется для так называемой «эскалации типов».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...