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

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

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)

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

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

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

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

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

Desafortunadamente, Java no tiene map(). :)


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.


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


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

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.


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);
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.