嵌套集合上的迭代器

时间:2010-02-19 12:32:00

标签: java collections iterator

我在Java中有两个数据结构:
一个叫做DebateAssignment,有5个DebateTeam对象,每个对象都包含一个包含的特定枚举

{JUDGE, PROP1, PROP2, OP1, OP2}

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

我将如何做到这一点?

4 个答案:

答案 0 :(得分:5)

单向,使用google-collections / guava

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

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

答案 1 :(得分:4)

假设DebateAssignment有类似

的内容
public Collection<DebateTeam> getDebateTeams();

您想要Iterator<DebateTeam>

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

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...
}

答案 2 :(得分:2)

可能最简单的方法是:

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

当然你可以编写一个实现Iterator<DebateTeam>的新类来“展平”嵌套迭代器,但这有点牵扯,因为你必须明确地跟踪这两个迭代器...(参见Clinton的答案)详细信息)。

答案 3 :(得分:0)

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

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