Como faço para descobrir qual o tipo de cada objeto está em um ArrayList ?

StackOverflow https://stackoverflow.com/questions/106336

Pergunta

Eu tenho um ArrayList composta de diferentes elementos importados de um db, constituídos de strings, números, duplos e ints. Existe uma maneira de usar uma técnica tipo reflexão para descobrir o que cada tipo de dados cada elemento detém?

FYI:. A razão por que há tantos tipos de dados é que este é um pedaço de código java que está sendo escrito para ser implementado com diferentes DB

Foi útil?

Solução

Em C #:
fixo com recomendação 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);
    }
    ...
}

Em Java:

ArrayList<Object> list = ...;
for (Object o : list) {
    if (o instanceof Integer)) {
        handleInt((Integer o).intValue());
    }
    else if (o instanceof String)) {
        handleString((String)o);
    }
    ...
}

Outras dicas

Você pode usar o método getClass(), ou você pode usar instanceof. Por exemplo

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

ou

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

Note que instanceof irá corresponder subclasses. Por exemplo, de C é uma subclasse de A, em seguida, o seguinte será verdadeira:

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

No entanto, o seguinte será false:

C c = new C();
assert !c.getClass().equals(A.class)
for (Object object : list) {
    System.out.println(object.getClass().getName());
}

Você quase nunca querem que você usar algo como:

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

porque você não está respondendo por possíveis subclasses. Você realmente quer usar Classe # IsAssignableFrom:

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

Em Java basta usar o operador instanceof. Isso também vai cuidar de subclasses.

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

Apenas chamada .getClass() em cada Object em um loop.

Infelizmente, Java não tem map(). :)

InstanceOf funciona se você não dependem de classes específicas, mas também ter em mente que você pode ter valores nulos na lista, então obj.getClass () irá falhar, mas instanceof sempre retorna false em null.

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

em vez de usar object.getClass().getName() você pode usar object.getClass().getSimpleName(), porque ele retorna um nome de classe simples, sem um nome de pacote.

por exemplo,

Object[] intArray = { 1 }; 

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

dá,

java.lang.Integer
Integer

Você diz que "este é um pedaço de código java sendo escrito", a partir do qual deduzo que ainda há uma chance de que você poderia projetá-lo de maneira diferente.

Ter um ArrayList é como ter uma coleção de coisas. Ao invés da força do instanceof ou getClass cada vez que você pegar um objeto da lista, por que não projetar o sistema para que você obtenha o tipo do objeto quando você recuperá-lo do DB, e armazená-lo em uma coleção do tipo apropriado de objeto?

Ou, você pode usar uma das muitas bibliotecas de acesso a dados que existem para fazer isso por você.

Se você espera que os dados a ser numérico de alguma forma, e tudo que você estiver interessado em fazer é converter o resultado para um valor numérico, gostaria de sugerir:

for (Object o:list) {
  Double.parseDouble(o.toString);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top