在 Java 中的同一列表中嵌套 for-each?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16286742/
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
Nested for-each on same list in Java?
提问by Belizzle
I have a list of lists of Integer that I'm using to build chains based on an input file. The input specifies pairs (e.g. "3, 1" indicates that 1 replaces 3 in the application), and there are overlaps in the pairs (e.g. "3, 1" and "1, 4" would mean that 1 replaces 3 and 4 replaces 1, so ultimately, 4 replaces 3).
我有一个 Integer 列表的列表,我用它来基于输入文件构建链。输入指定对(例如,“3, 1”表示应用程序中的 1 替换 3),并且这些对中存在重叠(例如,“3, 1”和“1, 4”将表示 1 替换 3 和 4 替换1,所以最终,4 取代 3)。
In order to reduce all of the pairs into their final chains, I have a list containing lists of all the pairs, and then I find which entries in the list overlap and append to the chains as needed, removing the pair that has been appended to another. This is how I am attempting to do this, but I know the failure is in doubling up the iterator references:
为了将所有对减少到它们的最终链中,我有一个包含所有对的列表的列表,然后我找到列表中的哪些条目重叠并根据需要附加到链中,删除已附加到的对其他。这就是我尝试这样做的方式,但我知道失败在于将迭代器引用加倍:
for (ArrayList<Integer> outerChain : chains) {
for (ArrayList<Integer> innerChain : chains) {
if (outerChain.get(0).equals(innerChain.get(innerChain.size() - 1))) {
outerChain.remove(0);
innerChain.addAll(outerChain);
chains.remove(outerChain);
break;
}
}
}
As an example of the input/desired output from this operation:
作为此操作的输入/所需输出的示例:
{<1,3>,<2,7>,<7,9>,<8,12>,<9,1>,<6,8>}
being individual lists corresponding to input pairs, the output would be:
作为与输入对相对应的单个列表,输出将是:
{<2,7,9,1,3>,<6,8,12>}
Is there a way I can nest iterators like this such that the references within each iterator are updated when removing or updating for one or the other?
有没有一种方法可以嵌套这样的迭代器,以便在删除或更新一个或另一个迭代器时更新每个迭代器中的引用?
Thanks in advance for the help!
在此先感谢您的帮助!
回答by Eran
So when should you use the for-each loop? Any time you can. It really beautifies your code. Unfortunately, you cannot use it everywhere. Consider, for example, the expurgate method. The program needs access to the iterator in order to remove the current element. The for-each loop hides the iterator, so you cannot call remove. Therefore, the for-each loop is not usable for filtering. Similarly it is not usable for loops where you need to replace elements in a list or array as you traverse it. Finally, it is not usable for loops that must iterate over multiple collections in parallel. These shortcomings were known by the designers, who made a conscious decision to go with a clean, simple construct that would cover the great majority of cases.
那么什么时候应该使用 for-each 循环呢?任何时候都可以。它确实美化了您的代码。不幸的是,你不能在任何地方使用它。例如,考虑 expurgate 方法。程序需要访问迭代器才能删除当前元素。for-each 循环隐藏了迭代器,因此您无法调用 remove。因此,for-each 循环不可用于过滤。同样,它不适用于需要在遍历列表或数组时替换元素的循环。最后,它不适用于必须并行迭代多个集合的循环。设计师们都知道这些缺点,他们有意识地决定采用一个干净、简单的结构来覆盖绝大多数情况。
You shouldn't use the for-each loop when you remove elements from the list or array while traversing it. Therefore you should use the explicit iterator syntax in your case.
在遍历列表或数组时从列表或数组中删除元素时,不应使用 for-each 循环。因此,您应该在您的情况下使用显式迭代器语法。
Something like this :
像这样的事情:
Iterator<ArrayList<Integer>> outer = chains.iterator ();
while (outer.hasNext ()) {
ArrayList<Integer> outerChain = outer.next();
Iterator<ArrayList<Integer>> inner = chains.iterator ();
while (inner.hasNext ()) {
ArrayList<Integer> innerChain = inner.next();
if (outerChain.get(0).equals(innerChain.get(innerChain.size() - 1))) {
outerChain.remove(0);
innerChain.addAll(outerChain);
outer.remove();
break;
}
}
}
回答by Peter Lawrey
Once you modify a list in an iterator you can't use that iterator. Fortunately you need to start again anyway so you have a natural solution
一旦在迭代器中修改了列表,就不能使用该迭代器。幸运的是,无论如何你都需要重新开始,这样你就有了一个自然的解决方案
OUTER: while(chains.size() > 1) {
for (ArrayList<Integer> outerChain : chains) {
for (ArrayList<Integer> innerChain : chains) {
if (outerChain.get(0) == innerChain.get(innerChain.size() - 1)) {
outerChain.remove(0);
innerChain.addAll(outerChain);
chains.remove(outerChain);
continue OUTER;
}
}
}
break; // no more matches found.
}
回答by Andremoniy
I do not see any problem with double for-each-loops, but I see a big problem with ==
operator, which you are using for comparing Integer
objects. This is totally incorrect. You should use .equals()
method instead.
我认为双 for-each-loops 没有任何问题,但我发现==
运算符有一个大问题,您使用它来比较Integer
对象。这是完全不正确的。您应该改用.equals()
方法。
回答by Nathan Adduci
use this as a guide:
以此为指导:
for(int[] i: sampleIntArray)
{
for(int current: i)
{
//sample code here;
}
}