2009-10-25 50 views
0

下面的代码改变一个迭代对象的属性只是产生问题的例子:的Java:在遍历它

public static void main(String[] args) { 
    Collection<Integer> src = new ArrayList<Integer>(); 
    Collection<Integer> dest = new ArrayList<Integer>(); 

    src.add(2); 
    src.add(7); 
    src.add(3); 
    src.add(2201); 
    src.add(-21); 

    dest.add(10); 

    while (src.size() != 0) { 
    for (int i : dest) { 
    int min = Collections.min(src); 
    dest.add(min); 
    src.remove(min); 
    } 
    } 

} 

我想要做的就是从SRC在到dest移动一切具体的顺序。 (在这里,就是为最小值,但是这只是从我的真正的问题简单化。)不过,我修改DEST同时遍历它,并收到以下错误:

Exception in thread "main" java.util.ConcurrentModificationException 
at java.util.AbstractList$Itr.checkForComodification(Unknown Source) 
at java.util.AbstractList$Itr.next(Unknown Source) 
at nth23.experimental.MoveBetweenSets.main(MoveBetweenSets.java:25) 

我怎样才能解决这个?

+0

基于“我想要做的是从特定的顺序移动一切从src到dest” - 不能你的排序src然后只需添加所有目标? (Collections.sort,Collections.addAll)? –

回答

1

可以在迭代它使用iterator.remove()了从集合(当然,有些收藏)删除 - 但你通常不能添加到它。

然而,随着newacct在评论中指出,ListIterator接口包括add方法,所以你应该能够改变这样的代码:

public static void main(String[] args) { 
    Collection<Integer> src = new ArrayList<Integer>(); 
    List<Integer> dest = new ArrayList<Integer>(); 

    src.add(2); 
    src.add(7); 
    src.add(3); 
    src.add(2201); 
    src.add(-21); 

    dest.add(10); 

    while (src.size() != 0) { 
    for (ListIterator<Integer> li = dest.listIterator(); li.hasNext() ;) { 
    int min = Collections.min(src); 
    li.add(min); 
    src.remove(min); 
    } 
    } 
} 

注意,现在dest必须是声明为List而不是Collection,并且您需要明确扩展for循环。不过,我仍然不确定为什么你首先要重复dest。你在每次迭代中都添加一个元素,所以你永远不会到达最后。

这是怎么回事?

while (src.size() != 0) { 
    int min = Collections.min(src); 
    dest.add(min); 
    src.remove(min); 
    } 

或者,正如其他人所说,只需拨打sort() - 通过在一个自定义Comparator如果您需要。

+0

这不是事实。如果您使用ListIterator迭代它们,您可以添加到列表并更改元素。 – newacct

+0

哦,你是绝对正确的。忘记了那位ListIterator。将编辑。 –

0

正如你所看到的,当你迭代它时你不能改变一个集合。 (更确切地说,你可以改变它,但是你不能继续迭代)

你可以迭代列表的副本或使用传统的for循环。

无论哪种方式,请确保您完全理解在修改集合时索引发生了什么;否则,您的代码将无法正常工作。

如需更具体的建议,请告诉我们您的实际情况。

0

您可以创建临时列表,以便在不更改dest和src的情况下跟踪应该添加和删除的内容。然后,在循环之外使用临时列表添加和删除必要的项目。但像Jon Skeet所说,更具体的要求会有所帮助。我认为有一些限制。

2

是否有一个原因,你不能只是将源列表复制到目的地列表,然后对其进行排序?

 
Collection<Integer> dest = new ArrayList<Integer>(src); 
Collections.sort(dest); 
2

这是一种解决方法:

while (!src.isEmpty()) { 
    int min = Collections.min(src); 
    dest.add(min); 
    src.remove(min); 
} 

但这可能更会使事情变得更糟。更具体一点(正如Jon所说)。

1

说实话,我没有得到for (int i : dest)部分。如果你删除它,实际上没有问题,这回答了这个问题:)