Jak mogę się dowiedzieć, jakiego typu jest każdy obiekt w ArrayList <Object>?

87

Mam ArrayList składającą się z różnych elementów zaimportowanych z bazy danych, składających się z ciągów, liczb, podwójnych i int. Czy istnieje sposób na użycie techniki typu odbicia, aby dowiedzieć się, jakie typy danych przechowuje każdy element?

FYI: Powodem, dla którego istnieje tak wiele typów danych, jest to, że jest to fragment kodu Java, który został napisany w celu zaimplementowania w różnych bazach danych.

WolfmanDragon
źródło

Odpowiedzi:

100

W C #:
Naprawiono z rekomendacją Mike'a

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

W Javie:

ArrayList<Object> list = ...;
for (Object o : list) {
    if (o instanceof Integer)) {
        handleInt((Integer o).intValue());
    }
    else if (o instanceof String)) {
        handleString((String)o);
    }
    ...
}
Frank Krueger
źródło
3
właściwie zamiast używać o.GetType () == typeof (int)) po prostu powiedz if (o is int);
Michael Brown,
A jeśli zdarzy ci się martwić o każdą nanosekundę, „as” zaoszczędzi ci kilka w porównaniu do „jest” przy obsadzie.
Neil,
47
Nie możesz po prostu zrobić instanceofw przypadku Java?
Razor Storm
2
Dla przypadku Integer powinien to być również Integer.class, właśnie wypróbowałem Integer.TYPE nie działa.
alan turing
(int) onie działa w Javie. Generuje komunikat o błędzie Cannot cast from Object to int. Użyj (Integer o).intValue()zamiast tego.
Max
54

Możesz użyć getClass()metody lub możesz użyć instanceof. Na przykład

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

lub

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

Zauważ, że instanceof będzie pasował do podklas. Na przykład of Cjest podklasą klasy A, wtedy spełnione będą następujące warunki:

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

Jednak następujące informacje będą fałszywe:

C c = new C();
assert !c.getClass().equals(A.class)
faran
źródło
45
for (Object object : list) {
    System.out.println(object.getClass().getName());
}
Fabian Steeg
źródło
7
nie zapomnij o null, jeśli jest to możliwe na twojej liście. Otrzymasz NullPointerExceptions z tego przykładu z wartościami null.
John Gardner,
13

Prawie nigdy nie chcesz, abyś używał czegoś takiego jak:

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

ponieważ nie bierzesz pod uwagę możliwych podklas. Naprawdę chcesz użyć klasy # isAssignableFrom:

Object o = ...
if (Foo.class.isAssignableFrom(o)) {
    ...
}
Heath Borders
źródło
5

W Javie wystarczy użyć operatora instanceof. To również zajmie się podklasami.

ArrayList<Object> listOfObjects = new ArrayList<Object>();
for(Object obj: listOfObjects){
   if(obj instanceof String){
   }else if(obj instanceof Integer){
   }etc...
}
Reid Mac
źródło
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());
            }
        }
    }
}
garncarz
źródło
4

Po prostu zadzwoń .getClass()do każdego Objectw pętli.

Niestety Java nie ma map(). :)

skiphoppy
źródło
3

Instanceof działa, jeśli nie jesteś zależny od określonych klas, ale pamiętaj również, że możesz mieć na liście wartości null, więc obj.getClass () nie powiedzie się, ale instanceof zawsze zwraca false dla null.

John Gardner
źródło
3

Ponieważ 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
            }
        });

Andrzej
źródło
2

zamiast używać object.getClass().getName()możesz użyć object.getClass().getSimpleName(), ponieważ zwraca prostą nazwę klasy bez dołączonej nazwy pakietu.

na przykład,

Object[] intArray = { 1 }; 

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

daje,

java.lang.Integer
Integer
Sufiyan Ghori
źródło
0

Mówisz "to jest napisany kawałek kodu java", z czego wnioskuję, że wciąż istnieje szansa, że ​​mógłbyś go zaprojektować w inny sposób.

Posiadanie ArrayList jest jak posiadanie kolekcji rzeczy. Zamiast wymuszać instancję lub getClass za każdym razem, gdy bierzesz obiekt z listy, dlaczego nie zaprojektować systemu tak, aby uzyskać typ obiektu podczas pobierania go z bazy danych i zapisać go w kolekcji odpowiedniego typu obiekt?

Możesz też użyć jednej z wielu istniejących bibliotek dostępu do danych, aby zrobić to za Ciebie.

shoover
źródło
0

Jeśli spodziewasz się, że dane będą w jakiejś formie liczbowe, a wszystko, co jesteś zainteresowany, to konwersja wyniku na wartość liczbową, proponuję:

for (Object o:list) {
  Double.parseDouble(o.toString);
}
DJClayworth
źródło