¿Cómo averiguo de qué tipo es cada objeto en un ArrayList <Object>?

87

Tengo una ArrayList formada por diferentes elementos importados de una base de datos, formada por cadenas, números, dobles e ints. ¿Hay alguna forma de utilizar una técnica de tipo de reflexión para averiguar qué tipo de datos contiene cada elemento?

FYI: La razón por la que hay tantos tipos de datos es que se trata de un fragmento de código Java que se está escribiendo para implementarse con diferentes bases de datos.

Hombre LoboDragón
fuente

Respuestas:

100

En C #:
corregido con la recomendación de 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);
    }
    ...
}

En Java:

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
fuente
3
en realidad, en lugar de usar o.GetType () == typeof (int)) solo diga if (o es int);
Michael Brown
Y si le preocupa cada nanosegundo, "as" le ahorrará unos pocos en comparación con "es" con un yeso.
Neil
47
¿No puedes simplemente hacer instanceofen el caso de Java?
Razor Storm
2
Para el caso de Integer, también debería ser Integer.class, acabo de intentar Integer.TYPE no funciona.
Alan Turing
(int) ono funciona en Java. Produce el mensaje de error Cannot cast from Object to int. Úselo en su (Integer o).intValue()lugar.
Máximo
54

Puede usar el getClass()método o puede usar instanceof. Por ejemplo

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

o

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

Tenga en cuenta que instanceof coincidirá con las subclases. Por ejemplo, de Ces una subclase de A, entonces se cumplirá lo siguiente:

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

Sin embargo, lo siguiente será falso:

C c = new C();
assert !c.getClass().equals(A.class)
faran
fuente
45
for (Object object : list) {
    System.out.println(object.getClass().getName());
}
Fabian Steeg
fuente
7
no se olvide de null si es posible en su lista. Obtendrá NullPointerExceptions de este ejemplo con nulos.
John Gardner
13

Casi nunca querrás usar algo como:

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

porque no está contabilizando posibles subclases. Realmente desea usar Class # isAssignableFrom:

Object o = ...
if (Foo.class.isAssignableFrom(o)) {
    ...
}
Heath Borders
fuente
5

En Java, simplemente use el operador instanceof. Esto también se ocupará de las subclases.

ArrayList<Object> listOfObjects = new ArrayList<Object>();
for(Object obj: listOfObjects){
   if(obj instanceof String){
   }else if(obj instanceof Integer){
   }etc...
}
Reid Mac
fuente
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());
            }
        }
    }
}
alfarero
fuente
4

Solo llame .getClass()a cada uno Objecten un bucle.

Desafortunadamente, Java no tiene map(). :)

skiphoppy
fuente
3

Instanceof funciona si no depende de clases específicas, pero también tenga en cuenta que puede tener nulos en la lista, por lo que obj.getClass () fallará, pero instanceof siempre devuelve falso en nulo.

John Gardner
fuente
3

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

Andrés
fuente
2

en lugar de usar object.getClass().getName()puede usar object.getClass().getSimpleName(), porque devuelve un nombre de clase simple sin un nombre de paquete incluido.

por ejemplo,

Object[] intArray = { 1 }; 

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

da,

java.lang.Integer
Integer
Sufiyan Ghori
fuente
0

Dices "esto es un fragmento de código Java que se está escribiendo", de lo que infiero que todavía existe la posibilidad de que puedas diseñarlo de una manera diferente.

Tener una ArrayList es como tener una colección de cosas. En lugar de forzar la instancia de o getClass cada vez que toma un objeto de la lista, ¿por qué no diseñar el sistema para que obtenga el tipo de objeto cuando lo recupere de la base de datos y lo almacene en una colección del tipo apropiado de ¿objeto?

O bien, puede usar una de las muchas bibliotecas de acceso a datos que existen para hacer esto por usted.

shoover
fuente
0

Si espera que los datos sean numéricos de alguna forma, y ​​todo lo que está interesado en hacer es convertir el resultado en un valor numérico, sugeriría:

for (Object o:list) {
  Double.parseDouble(o.toString);
}
DJClayworth
fuente