2009-12-08 3 views
1

У меня возникли трудности с использованием внутреннего Iterator.Проблема итератора внутреннего класса Java

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

} 

Затем я пытаюсь итерацию над ней:

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

Но это не работает. (См. Комментарий компилятора на проблемной строке). Что я здесь делаю неправильно?

На инженерной ноте, действительно ли это правильный способ решить мою проблему? У меня есть куча петель этой формы:

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

Поэтому я решил в Iterator будет чище. Является ли это излишним, иначе вы бы это сделали?

ответ

5

Там нет ничего принципиально плохого в два вложенных for петли, чтобы сделать это, но я думаю, что это было бы чище:

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 
} 

Возвращает новый экземпляр этого класса каждый раз, когда вам нужен итератор несколько предложений, и инициализировать sentences поле с помощью sentences.iterator();

(Edited после более внимательно читать ваш вопрос)

+0

N что вам может потребоваться добавить дополнительную проверку, если предложения могут быть пустыми. – Jorn

3
private class Words implements Iterator<String>, Iterable<String> { 
    ... 
    public Iterator<String> iterator() { 
    return this; 
    } 
    ... 
} 
Смежные вопросы