8
votes

Conversion des types d'itérateurs en Java

J'ai un itérateur que je veux convertir en itérateur . Typea et TypeB ne peuvent pas être directement lancés les uns aux autres mais je peux écrire une règle comment les jeter. Comment puis-je accomplir cela? Devrais-je étendre et remplacer itérateur SEXT, HASNEXT et supprimer des méthodes?


4 commentaires

Comment voulez-vous dire "ils ne peuvent pas être jetés directement les uns aux autres"? Pouvez-vous donner plus de contexte sur ce que vous essayez de faire et pourquoi?


Le nombre d'objets de typeb était trop élevé, alors je les garde dans une DB comme celui de Typea, mais évidemment dans le format DB qui est typique. Mais à la fin, ils contiennent tous deux un champ de cordes que je veux avoir un itérateur pour que je souhaite obtenir cette chaîne de typeea et faire un type avec elle et l'ajouter à l'itérateur, à la volée. Cela a-t-il du sens?


28: Cela a du sens, mais ce que vous décrivez ne casse pas. Donc, vous ne pouvez pas "écrire une règle comment les jeter". Vous pouvez écrire du code pour convertir typea à typeb , mais il ne sera pas coulé.


Vous avez raison, merci pour la pointe.


6 Réponses :


7
votes

écrire un Adaptateur . Voici un exemple en Java. Livre d'Oréilly 'Head First: Design Patterns' donne la meilleure explication sur le sujet.


0 commentaires

1
votes

Depuis que les génériques de Java sont juste une construction de la compilation, je sens que vous ferez mieux de jeter chaque élément que vous récupérez lors de l'invocation suivant () que de jeter les itérateurs.


0 commentaires

4
votes

Je suppose que vous devriez écrire votre propre itérateur (il peut implémenter Java.Util.iterator) avec votre règle ((conversion)) dans une méthode et l'utiliser.


1 commentaires

C'était ma réponse aussi :) Écrivez un itérateur qui prend un itérateur comme argument de constructeur, puis convertissez les objets au fur et à mesure que vous allez, dans la méthode suivante ().



2
votes

Vous pouvez utiliser l'extrait suivant:

public static void main(String... args){
    Iterator<TypeA> iteratorTypeA = methodToGetIteratorTypeA();
    Iterator<TypeB> iteratorTypeB = new IteratorConveter<TypeA, TypeB>(iteratorTypeA,
        new Converter<TypeA, TypeB>(){
            public TypeB convert(TypeA typeA){
                return null; //Something to convert typeA to type B
            }
        });
}

public class IteratorConveter<F, T> implements Iterator<T> {
    private final Converter<? super F, ? extends T> converter;
    private final Iterator<F> iterator;

    public IteratorConveter(Iterator<F> iterator, Converter<? super F, ? extends T> converter) {
        this.converter = converter;
        this.iterator = iterator;
    }

    public boolean hasNext() {
        return iterator.hasNext();
    }

    public T next() {
        return converter.convert(iterator.next());
    }

    public void remove() {
        iterator.remove();
    }
}


interface Converter<F, T> {
    T convert(F object);
}


1 commentaires

Désolé, je ne suis pas stupide, je ne suis pas un peu précipité, dans la partie de conversion, je suis instanciant d'une nouvelle instance de typeb et je le renvoie. Quelque chose comme: retour Nouveau DictionaryRony (doc.get ("nom"). Tostring (), doc.get ("ID"). Tostring ()); Mais je suis à court d'espace de tas, ce qui signifie que ces instances ne sont pas libérées. L'itérateur provient d'une interface DB afin qu'il ne détient pas plus de quelques instances à la fois en mémoire (je présume). Est-ce que je fais quelque chose de stupide ou tout dépend de typeB et c'est itérateur? Merci.



1
votes

Ce serait peut-être une bonne idée d'avoir une super-classe qu'ils partagent, mais cela dépend de la manière dont ces deux types sont définis exactement, ou éventuellement en avoir l'un d'entre eux hériter de l'autre, comme il semble qu'ils sont deux représentations pour les mêmes données. Cela résoudrait également vos problèmes d'itérateur.

ou vous pouvez écrire un conteneur qui utilise en interne l'un d'entre eux pour l'accès aux données et une représentation élégante au monde extérieur. Je me réfère à la "composition sur héritage".

Mais en substance, tout se résume à: Avez-vous pensé très fort de votre structure de classe? Êtes-vous sûr que c'est aussi bon que possible?


0 commentaires

19
votes

Vous n'avez pas besoin d'écrire cela vous-même. GUAVA (anciennement Google-collections) Vous avez couvert itérateurs.transform (...)

Vous fournissez votre itérateur et une fonction convertit Typea à TypeB et vous avez terminé. xxx


3 commentaires

Belle solution. Mais que si nous voulons jeter une exception à l'intérieur de la méthode Apply ()? Actuellement, il n'est pas permis mais la signature applicable ().


Vous pouvez toujours lancer une exception non cochée, ce qui est généralement la meilleure idée de toute façon.


En fait, j'ai besoin de lancer une exception vérifiée, donc j'ai fini par créer ma propre méthode de transformation. Merci