Java内部类迭代器问题

时间:2009-12-08 18:45:26

标签: java iterator dry software-design inner-classes

我在使用内部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();          
    }

}

然后,我尝试迭代它:

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会更干净。这有点矫枉过正,还是有另外一种方法可以做到这一点?

2 个答案:

答案 0 :(得分: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();字段

(更仔细地阅读你的问题后编辑)

答案 1 :(得分:3)

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