Как мне узнать, к какому типу относится каждый объект в ArrayList<Object>?

StackOverflow https://stackoverflow.com/questions/106336

Вопрос

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

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

Это было полезно?

Решение

В 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((Integer o).intValue());
    }
    else if (o instanceof String)) {
        handleString((String)o);
    }
    ...
}

Другие советы

Вы можете использовать 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)
for (Object object : list) {
    System.out.println(object.getClass().getName());
}

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

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

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

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

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

ArrayList<Object> listOfObjects = new ArrayList<Object>();
for(Object obj: listOfObjects){
   if(obj instanceof String){
   }else if(obj instanceof Integer){
   }etc...
}
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());
            }
        }
    }
}

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

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

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

Начиная с 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
            }
        });

вместо того, чтобы использовать 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

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

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

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

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

for (Object o:list) {
  Double.parseDouble(o.toString);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top