Як дізнатись, якого типу є кожен об’єкт у ArrayList <Object>?


87

У мене є ArrayList, що складається з різних елементів, імпортованих з db, що складається з рядків, чисел, дублів та ints. Чи можна використати техніку типу відображення, щоб з’ясувати, що містить кожен тип даних у кожному елементі?

FYI: Причина того, що існує так багато типів даних, полягає в тому, що це частина Java-коду, яка пишеться для реалізації з різними базами даних.

Відповіді:


100

У 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);
    }
    ...
}

3
насправді замість використання o.GetType () == typeof (int)) просто скажіть if (o це int);
Michael Brown

І якщо вас турбує кожна наносекунда, "як" заощадить вас кілька порівняно з "є" з гіпсом.
Ніл

47
Ви не можете просто зробити instanceofу випадку Java?
Razor Storm

2
Для випадку Integer це також повинен бути Integer.class, я щойно спробував Integer.TYPE не працює.
алан тюрінг

(int) oне працює в Java. Він видає повідомлення про помилку Cannot cast from Object to int. Використовуйте (Integer o).intValue()замість цього.
Макс.

54

Ви можете використовувати getClass()метод, або ви можете використовувати instanceof. Наприклад

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

або

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

Зверніть увагу, що instanceof буде відповідати підкласам. Наприклад, of Cє підкласом A, тоді буде справедливим наступне:

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

Однак наступним буде помилковим:

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

45
for (Object object : list) {
    System.out.println(object.getClass().getName());
}

7
не забувайте про null, якщо це можливо у вашому списку. Ви отримаєте NullPointerExceptions з цього прикладу з нулями.
Джон Гарднер,

13

Ви майже ніколи не хочете використовувати щось на зразок:

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

тому що ви не враховуєте можливі підкласи. Ви дійсно хочете використовувати клас # isAssignableFrom:

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

5

У Java просто використовуйте оператор instanceof. Це також подбає про підкласи.

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

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

4

Просто зателефонуйте .getClass()кожному Objectв циклі.

На жаль, Java не має map(). :)


3

Instanceof працює, якщо ви не залежате від конкретних класів, але також майте на увазі, що у вас може бути нуль у списку, тому obj.getClass () не вдасться, але instanceof завжди повертає false на null.


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

0

Ви кажете "це частина Java-коду, що пишеться", з чого я роблю висновок, що все ще існує ймовірність того, що ви можете спроектувати його по-іншому.

Наявність ArrayList - це все одно, що мати колекцію речей. Замість того, щоб змушувати instanceof або getClass кожного разу, коли ви берете об’єкт зі списку, чому б не сконструювати систему так, щоб ви отримали тип об’єкта, коли ви отримуєте його з БД, і не зберігали його у колекції відповідного типу об'єкт?

Або ви можете скористатися однією з багатьох існуючих бібліотек доступу до даних, щоб зробити це за вас.


0

Якщо ви очікуєте, що дані в якійсь формі будуть числовими, і все, що вам цікаво, - це перетворення результату в числове значення, я б запропонував:

for (Object o:list) {
  Double.parseDouble(o.toString);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.