7
votes

Traverser en toute sécurité un itérateur brut en Java?

J'utilise une bibliothèque tierce qui renvoie un itérateur brut, par exemple

Iterator<?> children = element.getChildElements();
while (null != children && children.hasNext()) {
  Object obj = children.next();
  ActualObject child = null;
    if (obj instanceof ActualObject)
      child = (ActualObject)obj;
    ...
}


4 commentaires

Que voulez-vous arriver s'il y a des objets retournés par l'itérateur qui sont pas instances de réticalObject ?


Que devrait-on faire si le type de l'enfant n'est pas réalisé? Si vous n'avez pas besoin de continuer, je pense que la capture de ClasscastException pourrait être le moyen le plus propre d'aller. Vous pouvez enregistrer le type inadéquation et aller de l'avant.


@pkading & @gangadhar - Je jetterais une exception.


La méthode de Guava (comme beaucoup de choses à Guava) existe pour faciliter la tâche plus facile et plus concise de faire quelque chose qui est plutôt verbeux dans le noyau Java, alors je ne m'attendrais donc pas à trouver quelque chose d'équivalent dans la JDK.


4 Réponses :


7
votes

GUAVA rend cela facile avec son Itérators.filter (itérateur , Classe ) méthode. Il renvoie un itérateur qui passe essentiellement tous les éléments de l'itérateur donné qui n'est pas une instance de type t : xxx

Vous pouvez évidemment parcourir l'itérateur résultant sans avoir à lancer chaque élément sur réticalObject et sans avoir à vous soucier de classcastexception . .


5 commentaires

Merci, c'est intéressant, mais en utilisant malheureusement Guava n'est pas une option pour moi.


@Segphault: Eh bien, puis lisez le code source et vérifiez comment ils l'ont fait.


Je soupçonne qu'ils ont fait la même chose que votre dernier exemple, mais simplement l'extraire dans un objet wrapper.


Oui, cela fait efficacement la même chose que le deuxième exemple, même s'il s'appuie sur le reste de leur code prédicat / filtrage.


@PKKeeding - à peu près: code.google.com/p/google-Collections/source/browse/trunk/src / ...



2
votes

Le moyen facile de gérer cela est simplement de le jeter et de vous assurer que, si le type change de ce que vous attendez à l'avenir, une exception sera lancée et vous serez informé. Vous voudrez vérifier que vous devez enregistrer les travaux d'exception et l'exception trouvera son chemin vers le fichier journal. Exceptions existent pour vous dire que quelque chose n'est pas ce que vous attendez, laissez-les faire leur travail.

Si vous ignorez silencieusement des éléments qui ne sont pas le type attendu, vous pouvez absorber les données dont vous avez besoin, cela ne ressemble pas à une bonne solution pour moi.


0 commentaires

2
votes

Votre dernière version semble être la voie à suivre, mais je suppose que nous pouvons améliorer cela un peu:

else{
    log.warn("Expected type: " + ActualObject.class + ", but got " + obj);
}


1 commentaires

Vous avez raison sur le chèque null, je vais supprimer ça. C'est une mauvaise API, de manière plus importante que la question de la question. J'ai hâte de ne plus jamais l'utiliser.



1
votes

car il semble que vous souhaitiez arrêter d'exécuter et jeter une exception si vous rencontrez un objet renvoyé par l'itérateur qui n'est pas une instance de réticalObject , alors je voudrais juste la jeter et avoir un Catch Block pour traiter le possible ClasscastException .


0 commentaires