Comment connaître le type de chaque objet dans un ArrayList <Object>?

87

J'ai une ArrayList composée de différents éléments importés d'une base de données, composée de chaînes, de nombres, de doubles et d'entiers. Existe-t-il un moyen d'utiliser une technique de type réflexion pour savoir ce que chaque type de données contient chaque élément?

FYI: La raison pour laquelle il y a tant de types de données est qu'il s'agit d'un morceau de code java en cours d'écriture pour être implémenté avec différentes bases de données.

WolfmanDragon
la source

Réponses:

100

En C #:
corrigé avec la recommandation 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
la source
3
en fait au lieu d'utiliser o.GetType () == typeof (int)) dites simplement if (o est int);
Michael Brown
Et si vous vous inquiétez de chaque nanoseconde, "as" vous en fera économiser quelques-uns par rapport à "est" avec un casting.
Neil
47
Tu ne peux pas juste faire instanceofdans le cas de java?
Razor Storm
2
Pour le cas Integer, cela devrait également être Integer.class, je viens d'essayer Integer.TYPE ne fonctionne pas.
alan turing le
(int) one fonctionne pas en Java. Il produit le message d'erreur Cannot cast from Object to int. Utilisez (Integer o).intValue()plutôt.
Max
54

Vous pouvez utiliser la getClass()méthode ou vous pouvez utiliser instanceof. Par exemple

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

ou

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

Notez que instanceof correspondra aux sous-classes. Par exemple, of Cest une sous-classe de A, alors ce qui suit sera vrai:

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

Cependant, ce qui suit sera faux:

C c = new C();
assert !c.getClass().equals(A.class)
Faran
la source
45
for (Object object : list) {
    System.out.println(object.getClass().getName());
}
Fabian Steeg
la source
7
n'oubliez pas de null si c'est possible dans votre liste. Vous obtiendrez des NullPointerExceptions à partir de cet exemple avec des valeurs nulles.
John Gardner
13

Vous ne voulez presque jamais utiliser quelque chose comme:

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

car vous ne tenez pas compte des sous-classes possibles. Vous voulez vraiment utiliser la classe # isAssignableFrom:

Object o = ...
if (Foo.class.isAssignableFrom(o)) {
    ...
}
Frontières de la santé
la source
5

En Java, utilisez simplement l'opérateur instanceof. Cela prendra également en charge les sous-classes.

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

Appelez simplement .getClass()chacun Objectdans une boucle.

Malheureusement, Java n'a pas map(). :)

sauter
la source
3

Instanceof fonctionne si vous ne dépendez pas de classes spécifiques, mais gardez également à l'esprit que vous pouvez avoir des valeurs nulles dans la liste, donc obj.getClass () échouera, mais instanceof retourne toujours false sur null.

John Gardner
la source
3

Depuis 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
la source
2

au lieu d'utiliser, object.getClass().getName()vous pouvez l'utiliser object.getClass().getSimpleName(), car il renvoie un nom de classe simple sans nom de package inclus.

par exemple,

Object[] intArray = { 1 }; 

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

donne,

java.lang.Integer
Integer
Soufiyan Ghori
la source
0

Vous dites "c'est un morceau de code java en cours d'écriture", d'où j'en déduis qu'il y a encore une chance que vous puissiez le concevoir d'une manière différente.

Avoir une ArrayList, c'est comme avoir une collection de choses. Plutôt que de forcer instanceof ou getClass chaque fois que vous prenez un objet de la liste, pourquoi ne pas concevoir le système de sorte que vous obteniez le type de l'objet lorsque vous le récupérez à partir de la base de données et le stockez dans une collection du type approprié de objet?

Ou, vous pouvez utiliser l'une des nombreuses bibliothèques d'accès aux données existantes pour le faire à votre place.

shoover
la source
0

Si vous vous attendez à ce que les données soient numériques sous une forme quelconque et que tout ce que vous souhaitez faire est de convertir le résultat en une valeur numérique, je suggère:

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