Como faço para descobrir que tipo cada objeto é em um ArrayList <Object>?

87

Eu tenho um ArrayList composto de diferentes elementos importados de um banco de dados, composto de strings, números, duplos e ints. Existe uma maneira de usar uma técnica de tipo de reflexão para descobrir o que cada tipo de dado que cada elemento contém?

Para sua informação: A razão pela qual existem tantos tipos de dados é que este é um pedaço de código Java sendo escrito para ser implementado com diferentes bancos de dados.

WolfmanDragon
fonte

Respostas:

100

Em C #:
corrigido 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);
    }
    ...
}
Frank Krueger
fonte
3
na verdade, em vez de usar o.GetType () == typeof (int)) apenas diga if (o é int);
Michael Brown
E se acontecer de você ficar preocupado com cada nanossegundo, "as" irá economizar alguns se comparado a "is" com elenco.
Neil
47
Você não pode simplesmente fazer instanceofno caso do java?
Razor Storm
2
Para o caso de Integer, também deve ser Integer.class, acabei de tentar Integer.TYPE não funciona.
Alan Turing de
(int) onão funciona em Java. Ele produz a mensagem de erro Cannot cast from Object to int. Use em seu (Integer o).intValue()lugar.
Máx.
54

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

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

ou

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

Observe que instanceof corresponderá a subclasses. Por exemplo, de Cé uma subclasse de A, então o seguinte será verdadeiro:

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

No entanto, o seguinte será falso:

C c = new C();
assert !c.getClass().equals(A.class)
faran
fonte
45
for (Object object : list) {
    System.out.println(object.getClass().getName());
}
Fabian Steeg
fonte
7
não se esqueça de null se for possível em sua lista. Você obterá NullPointerExceptions deste exemplo com nulos.
John Gardner de
13

Você quase nunca quer usar algo como:

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

porque você não está contabilizando possíveis subclasses. Você realmente deseja usar Class # isAssignableFrom:

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

Em Java, apenas use o operador instanceof. Isso também cuidará das subclasses.

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

Basta chamar .getClass()cada Objectum em um loop.

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

skiphoppy
fonte
3

Instanceof funciona se você não depende de classes específicas, mas também tenha em mente que você pode ter nulos na lista, então obj.getClass () irá falhar, mas instanceof sempre retorna falso em nulo.

John Gardner
fonte
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
            }
        });

Andrey
fonte
2

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

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
Sufiyan Ghori
fonte
0

Você diz "este é um trecho de código Java sendo escrito", do qual eu inferi que ainda há uma chance de que você possa projetá-lo de uma maneira diferente.

Ter um ArrayList é como ter uma coleção de coisas. Em vez de forçar o instanceof ou getClass toda vez que você pegar um objeto da lista, por que não projetar o sistema de forma que você obtenha o tipo do objeto quando recuperá-lo do banco de dados e armazene-o em uma coleção do tipo apropriado de objeto?

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

atirador
fonte
0

Se você espera que os dados sejam numéricos de alguma forma e tudo o que está interessado em fazer é converter o resultado em um valor numérico, sugiro:

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