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.

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

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)

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

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

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

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

Appelez simplement .getClass()chacun Objectdans une boucle.

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


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.


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


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

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.


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);
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.