2009-12-08 4 views
1

J'ai des difficultés à utiliser un Iterator intérieur.Java Inner Class Iterator Problème

private List<List<? extends HasWord>> sentences = new ArrayList<List<? extends HasWord>>(); 
private Iterator<String> wordIterator = new Words(); 
private class Words implements Iterator<String> { 

    int currSentence = 0; 
    int currWord = 0; 

    @Override 
    public boolean hasNext() { 
     return currSentence != sentences.size() - 1 && currWord != sentences.get(currSentence).size() - 1; 
    } 

    @Override 
    public String next() { 
     String nextWord = sentences.get(currSentence).get(currWord).word(); 
     currSentence++; 
     currWord++; 

     return nextWord; 
    } 

    @Override 
    public void remove() { 
     throw new UnsupportedOperationException();   
    } 

} 

Alors, je tente de itérer dessus:

for (String s : wordIterator) { //Error: Can only iterate over an array or an instance of java.lang.Iterable 
      words.add(s); 

Mais cela ne fonctionne pas. (Voir l'erreur du compilateur commentée sur la ligne problématique). Qu'est-ce que je fais mal ici?

Sur une note d'ingénierie, est la bonne façon de résoudre mon problème? J'ai un tas de boucles de cette forme:

for (List<? extends HasWord> sent : sentences) { 
     for (HasWord token : sent) { 
      //do stuff 
     } 
     } 

donc j'ai décidé un Iterator serait plus propre. Est-ce exagéré, ou y a-t-il une autre façon de le faire?

Répondre

5

Il n'y a rien fondamentalement mal à avoir deux boucles for imbriquées pour ce faire, mais je pense que ce serait plus propre:

public class Words implements Iterator<String> { 
    private final Iterator<HasWord> sentences; 
    private Iterator<String> currentSentence; 

    public boolean hasNext() { 
    return currentSentence.hasNext() || sentences.hasNext(); 
    } 

    public String next() { 
    if (currentSentence.hasNext()) { 
     return currentSentence.next(); 
    } 
    currentSentence = sentences.next(); 
    return next(); // will return the first word of the next sentence 
    } 
    //remove() omitted for brevity 
} 

Retour une nouvelle instance de cette classe chaque fois que vous avez besoin d'un itérateur sur plusieurs phrases, et initialiser le champ sentences utilisant sentences.iterator();

(Edité après avoir lu votre question plus attentivement)

+0

N Notez que vous devrez peut-être ajouter des vérifications supplémentaires si les phrases peuvent être vides. – Jorn

3
private class Words implements Iterator<String>, Iterable<String> { 
    ... 
    public Iterator<String> iterator() { 
    return this; 
    } 
    ... 
}