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.

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

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)

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

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

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

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

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

Niestety Java nie ma map(). :)


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.


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


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

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.


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);
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.