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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14513475/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 16:30:23  来源:igfitidea点击:

How do I iterate over multiple lists in parallel in Java?

javaiteratorguava

提问by darkuzul

I want to create a function to iterate over multiple lists. Now I know these lists have exactly the same size (and they can have different types too), for example:

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

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

And I want to be able to call a function which takes 3 elements at the same slice in each of these lists so for exemple:

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

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

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

I would like to do the equivalent of what I saw discussed in guava here but doesn't look implemented yet: http://code.google.com/p/guava-libraries/issues/detail?id=677

我想做我在番石榴中看到的等价物,但看起来还没有实现:http: //code.google.com/p/guava-libraries/issues/detail?id=677

They talk about doing Iterators.interleave or Iterators.zip and I would like to do something similar but I haven't been able to, so can someone please help me a bit? Thanks!

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

I would prefer to not have to get the size of one list and iterate over them by index, because in the future i can have lists of different sizes so i would like to use only 1 way to do this.

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

回答by Rob

A compound Iterator might be a cool idea, e.g.:

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

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

Then inside the implementation, you would create iterators for each of the lists, then loop through the items and put them into an array, then your consumption of that stuff would look something like:

然后在实现中,您将为每个列表创建迭代器,然后遍历项目并将它们放入一个数组中,然后您对这些内容的消耗将类似于:

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

What's nice about this solution is you are hiding all those details about whether one list ran out or not (of course you have to decide what you want to do if one does, but that could be wrapped inside as well).

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

回答by gerrytan

You can create a new thread and iterate your list there. Spawn multiple of this therad and you can iterate your list in parallel.

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

If you want to pass List of any template type, you can just specify your method parameter as List, although this might result in compiler warnings. Other thing you can try is pass the list as List<T extends Object> and do a runtime check of type T and action accordingly

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

However if by 'parallel' you are not referring to multithreading / concurrency -- instead just want to be able to iterate your 3 lists in one single loop, then something like this will do (warning code is rough example only -- not tested / complying with coding standard):

但是,如果通过“并行”,您不是指多线程/并发——而只是希望能够在一个循环中迭代您的 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
}

回答by Rob

I don't think you are really saying in parallel, since the values are being used to invoke a method. If you want the same elements from each list, concurrently skipping through different lists on different threads does you no good.

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

You just need to do a for loop and then call list1.get(i), list2.get(i), list3.get(i).

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