Domanda

Ho un ArrayList composto da diversi elementi importati da un db, composto da stringhe, numeri, doppi e ints. Esiste un modo per utilizzare una tecnica di tipo riflessione per scoprire che tipo di dati contiene ciascun elemento?

Cordiali saluti: La ragione per cui ci sono così tanti tipi di dati è che questo è un pezzo di codice java che viene scritto per essere implementato con DB diversi.

È stato utile?

Soluzione

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

Altri suggerimenti

Puoi usare il metodo getClass () , oppure puoi usare instanceof. Ad 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, 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)
for (Object object : list) {
    System.out.println(object.getClass().getName());
}

Non vuoi quasi mai usare qualcosa come:

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

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

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

In Java basta usare l'operatore instanceof. Questo si occuperà anche delle sottoclassi.

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

Basta chiamare .getClass () su ogni Object in un ciclo.

Sfortunatamente, Java non ha map () . :)

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

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

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

ad 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

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

Avere una ArrayList è come avere una raccolta di cose. Invece di forzare l'istanza di getClass ogni volta che si prende un oggetto dall'elenco, perché non progettare il sistema in modo da ottenere il tipo di oggetto quando lo si recupera dal DB e memorizzarlo in una raccolta del tipo appropriato di obiettare?

In alternativa, è possibile utilizzare una delle molte librerie di accesso ai dati esistenti per farlo.

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

for (Object o:list) {
  Double.parseDouble(o.toString);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top