Come faccio a sapere di che tipo è ogni oggetto in un ArrayList <Object>?


87

Ho un ArrayList composto da diversi elementi importati da un db, composto da stringhe, numeri, doppi e int. C'è un modo per utilizzare una tecnica del tipo di riflessione per scoprire cosa contiene ogni tipo di dati ogni elemento?

FYI: Il motivo per cui ci sono così tanti tipi di dati è che questo è un pezzo di codice java che viene scritto per essere implementato con diversi DB.

Risposte:


100

In C #:
risolto con la raccomandazione di Mike

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

In 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
in realtà invece di usare o.GetType () == typeof (int)) dì semplicemente if (o is int);
— Michael Brown

1
E se ti capita di essere preoccupato per ogni nanosecondo, "as" ti farà risparmiare alcuni rispetto a "is" con un cast.
— Neil

47
Non puoi farlo solo instanceofnel caso Java?
— Razor Storm

2
Per il caso Integer, dovrebbe anche essere Integer.class, ho appena provato Integer.TYPE non funziona.
— alan turing

(int) onon funziona in Java. Produce il messaggio di errore Cannot cast from Object to int. Usa (Integer o).intValue()invece.
— Max

54

Puoi usare il getClass()metodo o puoi usare instanceof. Per esempio

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

o

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

Nota che instanceof corrisponderà alle sottoclassi. Ad esempio, of Cè una sottoclasse di A, quindi sarà vero quanto segue:

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

Tuttavia, quanto segue sarà falso:

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

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

7
non dimenticare null se è possibile nella tua lista. Otterrai NullPointerExceptions da questo esempio con valori null.
— John Gardner,

13

Non vuoi quasi mai usare qualcosa come:

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

perché non stai tenendo conto delle possibili sottoclassi. Vuoi davvero usare Class # isAssignableFrom:

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

5

In Java è sufficiente utilizzare l'operatore instanceof. Questo si prenderà cura anche delle sottoclassi.

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

Basta chiamare .getClass()ciascuno Objectin un ciclo.

Sfortunatamente, Java non ha map(). :)


3

Instanceof funziona se non dipendi da classi specifiche, ma tieni presente anche che puoi avere valori nulli nell'elenco, quindi obj.getClass () fallirà, ma instanceof restituisce sempre false su null.


3

Poiché 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

invece di usare object.getClass().getName()puoi usare object.getClass().getSimpleName(), perché restituisce un semplice nome di classe senza un nome di pacchetto incluso.

per esempio,

Object[] intArray = { 1 }; 

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

dà,

java.lang.Integer
Integer

0

Dici "questo è un pezzo di codice java in fase di scrittura", da cui deduco che c'è ancora una possibilità che tu possa progettarlo in un modo diverso.

Avere un ArrayList è come avere una raccolta di cose. Piuttosto che forzare l'istanza di o getClass ogni volta che prendi un oggetto dalla lista, perché non progettare il sistema in modo da ottenere il tipo di oggetto quando lo recuperi dal DB e memorizzarlo in una raccolta del tipo appropriato di oggetto?

Oppure puoi usare una delle tante librerie di accesso ai dati esistenti per farlo per te.


0

Se ti aspetti che i dati siano numerici in qualche forma e tutto ciò che ti interessa è convertire il risultato in un valore numerico, suggerirei:

for (Object o:list) {
  Double.parseDouble(o.toString);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.