4

我想创建一个函数来迭代多个列表。现在我知道这些列表的大小完全相同(它们也可以有不同的类型),例如:

List<Integer> list1 = getList1();
List<String> list2 = getList2();
List<Long> list3 = getList3();
list1.size() == list2.size(); // returns true
list2.size() == list3.size(); // returns true

而且我希望能够调用一个函数,该函数在每个列表的同一切片中获取 3 个元素,例如:

int calculate(int elemList1, String elemList2, long elemList3) {...}

// iterator over the lists in parallel {
    int ret = calculate(elemList1, elemList2, elemList3);
// }

我想做与我在 guava 中讨论的内容等效的操作,但看起来尚未实现:http ://code.google.com/p/guava-libraries/issues/detail?id=677

他们谈论做 Iterators.interleave 或 Iterators.zip ,我想做类似的事情,但我做不到,所以有人可以帮我一下吗?谢谢!

我宁愿不必获取一个列表的大小并按索引对其进行迭代,因为将来我可以拥有不同大小的列表,所以我只想使用一种方法来做到这一点。

4

3 回答 3

11

复合迭代器可能是一个很酷的主意,例如:

Iterator<Array<?>> compoundIterator = createIterator(List1, List2, List3);

然后在实现内部,您将为每个列表创建迭代器,然后循环遍历这些项目并将它们放入一个数组中,然后您对这些东西的消费将如下所示:

while (compoundIterator.hasElements()){
    Array[] elements = compountIterator.nextElement();
    calculate(elements[0], elements[1], elements[2]);
}

这个解决方案的好处是你隐藏了所有关于一个列表是否用完的细节(当然你必须决定如果一个列表用完了,你想做什么,但这也可以包含在里面)。

于 2013-01-25T01:02:52.157 回答
1

您可以创建一个新线程并在那里迭代您的列表。产生多个这个 therad,你可以并行迭代你的列表。

如果要传递任何模板类型的 List,只需将方法参数指定为 List,尽管这可能会导致编译器警告。您可以尝试的另一件事是将列表作为 List<T extends Object> 传递,并对 T 类型进行运行时检查并相应地执行操作

但是,如果通过“并行”你不是指多线程/并发——而是只想能够在一个循环中迭代你的 3 个列表,那么这样的事情就可以了(警告代码只是粗略的例子——未经测试/符合编码标准):

List list1 = ...
List list2 = ...
List list3 = ...

for(int i=0,j=0,k=0; i<list1.size() && j<list2.size() && k<list3.size(); ++i,++j,++k)
{
   Object elemOfList1 = list1.get(i);
   Object elemOfList2 = list2.get(j);
   Object elemOfList3 = list3.get(k);
   // do something here
}
于 2013-01-25T00:43:30.380 回答
1

我不认为你真的在说并行,因为这些值被用来调用一个方法。如果您想要每个列表中的相同元素,同时跳过不同线程上的不同列表对您没有好处。

您只需要执行一个 for 循环,然后调用 list1.get(i)、list2.get(i)、list3.get(i)。

于 2013-01-25T00:48:42.913 回答