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 élément du Java en cours d’écriture destiné à être mis en œuvre avec différentes bases de données).
En C #:
Corrigé avec 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);
}
...
}
Vous pouvez utiliser la méthode getClass()
, 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 à des sous-classes. Par exemple, de C
est 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)
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)) {
...
}
Dans 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 Object
d'une boucle.
Malheureusement, Java n'a pas map()
. :)
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
}
});
Instanceof fonctionne si vous ne dépendez pas de classes spécifiques, mais gardez à l'esprit que vous pouvez avoir des valeurs NULL dans la liste. Obj.getClass () échouera, mais instanceof retournera toujours false à null.
au lieu d'utiliser object.getClass().getName()
, vous pouvez utiliser object.getClass().getSimpleName()
, car elle renvoie un nom de classe simple sans nom de package.
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 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 liste de tableaux, 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 sous une forme numérique et que tout ce qui vous intéresse est de convertir le résultat en valeur numérique, je suggérerais:
for (Object o:list) {
Double.parseDouble(o.toString);
}