【问题标题】:iterator over nested collections嵌套集合的迭代器
【发布时间】:2010-02-19 12:32:00
【问题描述】:

我在 Java 中有两个数据结构:
一个称为 DebateAssignment,有 5 个 DebateTeam 对象,每个对象都与一个特定的枚举相关联,该枚举包括

{JUDGE, PROP1, PROP2, OP1, OP2}

在另一个类中,我使用List<DebateAssignment>,并且我想创建一个迭代器,该迭代器将指向特定 DebateAssignment 中的特定 DebateTeam,并且我希望它遍历所有团队的所有任务,无缝地从一个任务到另一个任务。

我该怎么做呢?

【问题讨论】:

  • 你能显示DebateAssignment的代码吗?
  • 看了你的问题后,我进入了大脑融化。
  • 我猜Iterator<DebateAssignment> 不是你要找的,你清楚地知道它。你能澄清一下你的问题吗? (如果只是为了重新冻结可怜的 Roman 的大脑?)

标签: java collections iterator


【解决方案1】:

一种方式,使用google-collections / guava

return Iterables.concat(Iterables.transform(assignments,
    new Function<DebateAssigment, Collection<DebateTeam>>() {
      public Collection<DebateTeam> apply(DebateAssignment assignment) {
        return assignment.getDebateTeams();
      }
    }));

另一种方法是将数据存储为Multimap&lt;DebateAssignment, DebateTeam&gt;,然后简单地遍历values()entries() 视图。该数据结构不会对 JUDGE/PROP1/等进行建模。不过,协会。

【讨论】:

    【解决方案2】:

    假设DebateAssignment 有类似的东西

    public Collection<DebateTeam> getDebateTeams();
    

    你想要Iterator&lt;DebateTeam&gt;

    如果是这样,你想要类似的东西:

    public class DebateTeamIterator implements Iterator<DebateTeam> {
        private Iterator<DebateAssignment> iAssignment;
        private Iterator<DebateTeam> iTeam;
    
        public DebateTeamIterator(Iterator<DebateTeam> iAssignment) {
            this.iAssignment = iAssignment;
            if (iAssignment.hasNext())
                iTeam = iAssignment.next().getDebateTeams().iterator();
            else
                iTeam = new LinkedList<DebateTeam>().iterator();
        }
    
        public boolean hasNext() {
           return iTeam.hasNext() || iAssignment.hasNext();
        }
    
        public DebateTeam next() {
            if (!iTeam.hasNext())
                iTeam = iAssignment.next().getDebateTeams().iterator();
            return iTeam.next();
        }
    
        // ... other methods removed for brevity...
    }
    

    【讨论】:

    • 我很容易被指责为极端偏见,但我认为建议粘贴这么多行代码并不是一个好建议,这些代码行不平凡且未经证实,而不是(你猜对了)使用一个已经花费了很多人日来彻底测试和修复其实现的库。
    • 谢谢!以前从未实现过迭代器,这个答案真的很有帮助!
    【解决方案3】:

    可能最简单的方法是:

    List<DebateAssignment> list = ...
    List<DebateTeam> dtList = new ArrayList<DebateTeam>();
    for (DebateAssignment da : list) {
        dtList.addAll(da.getTeams());
    }
    return dtList.iterator();
    

    当然,您可以编写一个实现 Iterator&lt;DebateTeam&gt; 的新类,以“展平”嵌套迭代器,但这有点涉及,因为您必须明确跟踪两个迭代器......(有关详细信息,请参阅 Clinton 的回答这个)。

    【讨论】:

      【解决方案4】:

      您可以扩展像 ArrayList 之类的列表实现,并添加一个方法来返回执行您想要的 Iterator 实现。

      重写 iterator() 方法可能不是由它返回的迭代器的泛型类型的选项。

      【讨论】:

      • 其实我不明白他真正需要什么,但无论如何扩展收藏是一种不好的做法。您可以围绕 ArrayList 创建一个包装类并装饰一些方法,如 iterator()(即它是一个装饰器模式)。
      • 如果他真的想要一个一流的 List,我相信使用扩展要简单得多,因为对于组合,他必须实现所有 List 方法并将它们委托给实际的 List。我同意这个要求很奇怪。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-22
      • 2013-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多