Question

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'ints. Existe-t-il un moyen d'utiliser une technique de type réflexion pour déterminer la nature de chaque type de données que chaque élément contient?

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 à implémenter avec différentes bases de données.

Était-ce utile?

La solution

En C #:
Résolu 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);
    }
    ...
}

Autres conseils

Vous pouvez utiliser la méthode getClass () ou 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, C est une sous-classe de A , alors ce qui suit sera vrai:

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

Cependant, les éléments suivants seront faux:

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

Vous ne voulez presque jamais utiliser quelque chose comme:

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

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

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

En Java, utilisez simplement l'opérateur instanceof. Cela s’occupera également des sous-classes.

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

Appelez simplement .getClass () sur chaque objet d'une boucle.

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

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

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

au lieu d'utiliser object.getClass (). getName () , vous pouvez utiliser object.getClass (). getSimpleName () , car il renvoie un nom de classe simple sans un 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

Vous dites "ceci est un morceau de code Java en cours d'écriture", à partir duquel je déduis qu'il y a encore une chance que vous puissiez le concevoir différemment.

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

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

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

for (Object o:list) {
  Double.parseDouble(o.toString);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top