Frage

Ich habe Schwierigkeiten, ein inneres zu verwenden Iterator.

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();          
    }

}

Dann versuche ich, darüber zu iterieren:

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

Aber es funktioniert nicht. (Siehe Kommentar Compiler -Fehler in der problematischen Zeile). Was mache ich hier falsch?

In technischer Hinsicht ist der richtige Weg, um mein Problem zu lösen? Ich habe ein paar Schleifen dieser Form:

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

Also entschied ich mich für eine Iterator wäre sauberer. Ist das Overkill oder gibt es eine andere Möglichkeit, es zu tun?

War es hilfreich?

Lösung

Es ist nichts grundlegend falsch, wenn zwei verschachtelt sind for Loops, um dies zu tun, aber ich denke, das wäre sauberer:

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
}

Geben Sie jedes Mal, wenn Sie einen Iterator über mehrere Sätze benötigen, eine neue Instanz dieser Klasse zurück und initialisieren Sie die sentences Feld mit sentences.iterator();

(Bearbeitet, nachdem Sie Ihre Frage genauer gelesen haben)

Andere Tipps

private class Words implements Iterator<String>, Iterable<String> {
  ...
  public Iterator<String> iterator() {
    return this;
  }
  ...
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top