Java 对于每个,但多个迭代器类型?

发布于 2024-09-24 04:57:47 字数 223 浏览 4 评论 0原文

我有一个 Polygon 类,我希望在其上实现两个迭代器:一个迭代器仅运行一次所有元素(按交替顺序的顶点和边),另一个迭代器无限地(循环)运行它们。

从 for-each 用法的角度来看,我的猜测是,通过实现 Iterable.iterator()<,我只能将上述之一作为可与 for-each 一起使用的默认迭代器。 /代码>。这是正确的吗?或者有没有一种方法可以将 for-each 与两者一起使用?

I have a class Polygon on which I wish to implement two iterators: one to run through all elements (vertices and edges in alternating order) just ONCE, and another to run through them ad infinitum (cyclically).

From a for-each usage standpoint, my guess is that I am only going to be able to have one of the above be the default iterator that can be used with for-each, via implementation of Iterable.iterator(). Is this correct? Or is there a way I could use for-each with both?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

树深时见影 2024-10-01 04:57:47

只需添加两个返回两个不同迭代器的方法,每个迭代器对应一种情况:

public Iterable<String> eachOnce() {
    List<String> allResults = new ArrayList<String>();
    // fill list
    return allResults;
}

public Iterable<String> eachCyclic() {
    return new Iterable<String>() {

        public Iterator<String> iterator() {
            return new Iterator<String>() {

                public boolean hasNext() {
                    return true;
                }

                public String next() {
                    // TODO implement
                    return null;
                }

                public void remove() {
                    // do nothing
                }
            };

        }
    };
}

这只是一个字符串列表的示例,只需适应即可。

而不是

for (Polygon p : polygons) { }

仅仅使用

for (Polygon p : polygons.eachOnce()) { }

或循环版本

Just add two methods returning two different Iterators, one for each case:

public Iterable<String> eachOnce() {
    List<String> allResults = new ArrayList<String>();
    // fill list
    return allResults;
}

public Iterable<String> eachCyclic() {
    return new Iterable<String>() {

        public Iterator<String> iterator() {
            return new Iterator<String>() {

                public boolean hasNext() {
                    return true;
                }

                public String next() {
                    // TODO implement
                    return null;
                }

                public void remove() {
                    // do nothing
                }
            };

        }
    };
}

This is just an example with a List of Strings, just adapt.

Instead of

for (Polygon p : polygons) { }

just use

for (Polygon p : polygons.eachOnce()) { }

or the cyclic edition

美男兮 2024-10-01 04:57:47

我认为比已经提出的答案更好的答案是一种将任何 Iterable 转换为循环的方法。

public class IterableUtils {
  public static class CyclicIterator<T> implements Iterator<T> {
    private final Iterable<T> inner;
    private Iterator<T> currentIter;
    public CyclicIterator(Iterable<T> inner) {
      this.inner = inner;
    }
    public boolean hasNext() {
      if (currentIter == null || !currentIter.hasNext()) {
        currentIter = inner.iterator();
      }
      return currentIter.hasNext();
    }
    public T next() {
      if (currentIter == null || !currentIter.hasNext()) {
        currentIter = inner.iterator();
      }
      return currentIter.next();
    }
    public void remove() {
      currentIter.remove();
    }
  }
  public static <T> Iterable<T> cycle(final Iterable<T> i) {
    return new Iterable<T>() {
      public Iterator<T> iterator() { return new CyclicIterator<T>(i); }
    };
  }
}

然后,您可以在 Polygon 类中实现单个迭代器方法,并使用

for (Element e: polygon) {
  ...
}

迭代一次和

for (Element e: Cycle(polygon)) {
...
}

无限迭代。作为奖励,循环修饰符可以应用于任何可迭代对象。

An answer I think is better than those already presented is a method that turns any Iterable into a cyclic one.

public class IterableUtils {
  public static class CyclicIterator<T> implements Iterator<T> {
    private final Iterable<T> inner;
    private Iterator<T> currentIter;
    public CyclicIterator(Iterable<T> inner) {
      this.inner = inner;
    }
    public boolean hasNext() {
      if (currentIter == null || !currentIter.hasNext()) {
        currentIter = inner.iterator();
      }
      return currentIter.hasNext();
    }
    public T next() {
      if (currentIter == null || !currentIter.hasNext()) {
        currentIter = inner.iterator();
      }
      return currentIter.next();
    }
    public void remove() {
      currentIter.remove();
    }
  }
  public static <T> Iterable<T> cycle(final Iterable<T> i) {
    return new Iterable<T>() {
      public Iterator<T> iterator() { return new CyclicIterator<T>(i); }
    };
  }
}

Then you can just implement the single iterator method in the Polygon class and use

for (Element e: polygon) {
  ...
}

to iterate once and

for (Element e: cycle(polygon)) {
...
}

to iterate endlessly. As a bonus, the cycle modifier can be applied to any iterable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文