Вопрос по java, generics – Как узнать, какой тип у каждого объекта в ArrayList <Object> ?

87

У меня есть ArrayList, состоящий из различных элементов, импортированных из БД, состоящий из строк, чисел, двойных и целых чисел. Есть ли способ использовать технику типа отражения, чтобы узнать, какой тип данных содержит каждый элемент?

К сведению: причина того, что существует так много типов данных, заключается в том, что это фрагмент кода Java, который пишется для реализации с различными БД.

Ваш Ответ

12   ответов
5

В Java просто используйте оператор instanceof. Это также позаботится о подклассах.

ArrayList<Object> listOfObjects = new ArrayList<Object>();
for(Object obj: listOfObjects){
   if(obj instanceof String){
   }else if(obj instanceof Integer){
   }etc...
}
54

Вы можете использоватьgetClass() метод, или вы можете использовать instanceof. Например

for (Object obj : list) {
  if (obj instanceof String) {
   ...
  }
}

или же

for (Object obj : list) {
 if (obj.getClass().equals(String.class)) {
   ...
 }
}

Обратите внимание, что instanceof будет соответствовать подклассам. Например, изC это подклассAтогда будет верно следующее:

C c = new C();
assert c instanceof A;

Тем не менее, следующее будет ложным:

C c = new C();
assert !c.getClass().equals(A.class)
0

Вы говорите: «Это кусок написанного Java-кода», из которого я заключаю, что все еще есть шанс, что вы могли бы разработать его по-другому.

Наличие ArrayList похоже на коллекцию вещей. Вместо того, чтобы принудительно вызывать instanceof или getClass каждый раз, когда вы берете объект из списка, почему бы не спроектировать систему так, чтобы вы получали тип объекта при извлечении его из БД и сохраняли его в коллекции соответствующего типа объект?

Или вы можете использовать одну из множества существующих библиотек доступа к данным, чтобы сделать это для вас.

13

Вы почти никогда не хотите использовать что-то вроде:

Object o = ...
if (o.getClass().equals(Foo.class)) {
    ...
}

потому что вы не учитываете возможные подклассы. Вы действительно хотите использовать Class # isAssignableFrom:

Object o = ...
if (Foo.class.isAssignableFrom(o)) {
    ...
}
0

Если вы ожидаете, что данные будут числовыми в той или иной форме, и все, что вас интересует, это преобразовать результат в числовое значение, я бы предложил

for (Object o:list) {
  Double.parseDouble(o.toString);
}
4

Просто позвони.getClass() на каждойObject в петле.

К сожалению, Java не имеетmap(). :)

3

С Java 8


        mixedArrayList.forEach((o) -> {
            String type = o.getClass().getSimpleName();
            switch (type) {
                case "String":
                    // treat as a String
                    break;
                case "Integer":
                    // treat as an int
                    break;
                case "Double":
                    // treat as a double
                    break;
                ...
                default:
                    // whatever
            }
        });

2

Вместо того, чтобы использоватьobject.getClass().getName() ты можешь использоватьobject.getClass().getSimpleName(), потому что он возвращает простое имя класса без включенного имени пакета.

например,

Object[] intArray = { 1 }; 

for (Object object : intArray) { 
    System.out.println(object.getClass().getName());
    System.out.println(object.getClass().getSimpleName());
}

дает,

java.lang.Integer
Integer
45
for (Object object : list) {
    System.out.println(object.getClass().getName());
}
не забывайте о нуле, если это возможно в вашем списке. Вы получите NullPointerExceptions из этого примера с нулевыми значениями.
3

Экземпляр работает, если вы не зависите от определенных классов, но также имейте в виду, что в списке могут быть значения NULL, поэтому obj.getClass () завершится ошибкой, но instanceof всегда возвращает false при значении NULL.

5
import java.util.ArrayList;

/**
 * @author potter
 *
 */
public class storeAny {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        ArrayList<Object> anyTy=new ArrayList<Object>();
        anyTy.add(new Integer(1));
        anyTy.add(new String("Jesus"));
        anyTy.add(new Double(12.88));
        anyTy.add(new Double(12.89));
        anyTy.add(new Double(12.84));
        anyTy.add(new Double(12.82),);

        for (Object o : anyTy) {
            if(o instanceof String){
                System.out.println(o.toString());
            } else if(o instanceof Integer) {
                System.out.println(o.toString());   
            } else if(o instanceof Double) {
                System.out.println(o.toString());
            }
        }
    }
}
спасибо брат! отличное решение ...
99

В C #:
Исправлено с рекомендацией отМайк

ArrayList list = ...;
// List<object> list = ...;
foreach (object o in list) {
    if (o is int) {
        HandleInt((int)o);
    }
    else if (o is string) {
        HandleString((string)o);
    }
    ...
}

В Java:

ArrayList<Object> list = ...;
for (Object o : list) {
    if (o instanceof Integer)) {
        handleInt((int)o);
    }
    else if (o instanceof String)) {
        handleString((String)o);
    }
    ...
}
Вы не можете просто сделатьinstanceof в случае с Java?
И если вам случится беспокоиться о каждой наносекунде, "как" сэкономит вам немного по сравнению с "is" с броском.
(int)o ??? Cannot cast from Object to int
Для случая Integer это также должен быть Integer.class, я только что попробовал Integer.TYPE не работает.
на самом деле вместо использования o.GetType () == typeof (int)) просто скажите if (o is int);

Похожие вопросы