Question

Disons que j'ai un argument comme List<Object> objectList, qui m'est fourni en externe, et sur lequel je n'ai absolument aucun contrôle.Disons également que je connais toutes les possibilités pour les types downcastés de chaque élément de cette liste.Par exemple, disons que je sais que objectList contient des éléments de ces types : int, String, double, boolean.

Quelles approches puis-je utiliser pour filtrer objectList en listes séparées de chaque type déclassé sans en utilisant instanceof.Donc pour cet exemple, je veux mettre objectList en quelque chose qui ressemble à ceci :

class SpecificTypes
{
   List<Integer> intList;
   List<String> stringList;
   List<Double> doubleList;
   List<Boolean> booleanList;
}

Alors disons que je veux écrire une fonction qui ressemble à ceci :

SpecificTypes filterObjectList(List<Object> objectList)
{
   SpecificTypes results = new SpecificTypes();

   // Populate 'results' somehow
   // Without using cascading if/else or switch logic

   return results;
}

Mes recherches m'ont rapidement conduit au modèle de visiteur, mais je suis arrivé à la conclusion que je ne peux pas l'utiliser car j'aurais besoin de contrôler les types stockés dans objectList (ou du moins pouvoir les envelopper dans mes propres types dérivés), mais ceux-ci me sont fournis par une source externe, donc le modèle de visiteur semble impossible (n'est-ce pas ?).

Le sous-ensemble de types dérivés dans la liste d'objets est assez petit (bien qu'en réalité il soit plus grand que les 4 dans cet exemple), et ces types seront pas être en train de changer.Ce n'est donc pas grave si j'ai besoin d'écrire plusieurs spécialisations et répartiteurs.J'essaie d'éviter toute sorte d'instruction if/else ou switch en cascade.

Existe-t-il un moyen de spécialiser les fonctions qui permettraient de les résoudre correctement ?

Était-ce utile?

La solution

Non, par List<Object> objectList vous dites au langage que vous renoncez à la sécurité de type de tout ce qui est plus spécifique que Object qui concerne tout en Java.

Vous devez effectuer instanceof vérifie les types que vous souhaitez faire correspondre.Vous devez effectuer des castings parce que c'est effectivement ce que vous faites : le casting.Les hacks autour ne serviront à rien.

Autres conseils

Vous pouvez essayer de faire chaque conversion possible, et si cela n'échoue pas, ajoutez cet élément à la liste appropriée.

Ensuite, il vous suffit d'attraper l'exception ClassCastException.Mais réellement:Utiliser instanceof est la meilleure solution.

Une autre façon de procéder consiste à utiliser la méthode Class.isInstance() au lieu d'utiliser l'opérateur instanceof.

if (Boolean.class.isInstance(obj)){
  // handle this type
}

Pour le rendre plus flexible, vous pouvez définir une classe de base Handler qui gère une classe spécifique et remplir une liste avec une instance d'un gestionnaire spécifique pour chaque type que vous prenez en charge dans votre objectList.

Ensuite, pour chaque objet de objectList, vous parcourez votre liste de gestionnaires en appelant une méthode isHandling() qui renverrait true si c'est le type de gestionnaire pris en charge.Cette méthode utiliserait la méthode isInstance() pour vérifier le type.Si c'est vrai, vous pouvez appeler une autre méthode pour effectuer la gestion.De cette façon, si un nouveau type doit être pris en charge, il vous suffit de dériver un nouveau gestionnaire pour ce type et de l'enregistrer dans la liste des gestionnaires et c'est tout.

public abstract class Handler {

  protected Class<?> type;

  protected Handler(Class<?> type) {
    this.type = type;
  }

  public boolean isHandling(Object obj) {
    return type.isInstance(obj);
  }

  public abstract void handle(Object obj);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top