如何在Java中并行迭代多个列表?

时间:2013-01-25 00:39:18

标签: java iterator guava

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

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);
// }

我想做的相当于我在这里看到的番石榴,但是看起来还没有实现:http://code.google.com/p/guava-libraries/issues/detail?id=677

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

我宁愿不必获取一个列表的大小并通过索引迭代它们,因为将来我可以有不同大小的列表,所以我只想用一种方法来做这个。

3 个答案:

答案 0 :(得分:9)

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

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

然后在实现中,你将为每个列表创建迭代器,然后遍历项目并将它们放入一个数组中,然后你对这些东西的消费看起来像:

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

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

答案 1 :(得分:1)

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

如果要传递任何模板类型的List,只需将方法参数指定为List,尽管这可能会导致编译器警告。您可以尝试的其他方法是将列表传递给List&lt; T extends Object&gt;并相应地进行类型T和操作的运行时检查

但是,如果通过'parallel'你不是指多线程/并发 - 而只是想在一个循环中迭代你的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
}

答案 2 :(得分:1)

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

你只需要做一个for循环,然后调用list1.get(i),list2.get(i),list3.get(i)。