Java-在浏览ArrayList时向其添加元素
问题是我有一个方法Java-在浏览ArrayList时向其添加元素,java,Java,问题是我有一个方法createNode(),它在树中创建一个节点,然后如果它是一个离开节点,它会将它添加到ArrayList treeLeaves,我在浏览treeLeavesArrayList时调用这个方法,如下所示: Iterator<Tree> iter = treeLeaves.iterator(); while (iter.hasNext()) { iter.next().createNode(); } For (Tree
createNode()
,它在树中创建一个节点,然后如果它是一个离开节点,它会将它添加到ArrayList treeLeaves
,我在浏览treeLeaves
ArrayList时调用这个方法,如下所示:
Iterator<Tree> iter = treeLeaves.iterator();
while (iter.hasNext()) {
iter.next().createNode();
}
For (Tree cursor : treeLeaves) {
cursor.createNode();
}
但我一直有一个例外:
Exception in thread "main" java.util.ConcurrentModificationException
即使将下面的代码放入snychronized(treeLeaves){}
bloc。
我不知道这是否有用,但是;这是一个n-树。您需要一个ConcurrentList 阅读
此外,您在浏览arraylist时无法更改它。。。相反,如果您愿意,您可以使用tempoaray内存中的缓冲区编辑当前列表。您需要一个ConcurrentList 阅读
此外,您在浏览arraylist时无法更改它。。。相反,如果愿意,您可以使用tempoaray内存中的缓冲区编辑当前列表。这是因为在Java中,当创建迭代器时,您无法修改底层数据结构。增强的for循环“for(Tree cursor:treeLeaves))”使用迭代器
正如Ya所说,“在浏览arraylist时,您也不能更改它……相反,如果您愿意,您可以使用tempoaray内存中的缓冲区来编辑当前列表。”这是因为在Java中,当创建迭代器时,您无法修改基础数据结构。增强的for循环“for(Tree cursor:treeLeaves))”使用迭代器
正如Ya所说,“在浏览arraylist时,您也不能更改它……相反,如果您愿意,您可以使用tempoaray内存中的缓冲区来编辑当前列表。”简而言之,在大多数情况下,如果您更改集合的结构,所有仍然打开的迭代器都将无效。(相当多的例外,包括使用并发集合,或者通过迭代器进行修改,等等) 您的问题可以通过以下方式轻松演示:
List<Node> treeLeaves = new ArrayList<>();
//... add something to treeLeaves
for (leaf : treeLeaves) {
treeLeaves.add(new Node());
}
List treeLeaves=new ArrayList();
//... 在树视图中添加一些内容
用于(叶:树叶){
添加(新节点());
}
对于您的情况,可以通过创建一个新集合进行迭代来轻松解决:
List<Node> treeLeaves = new ArrayList<>();
//... add something to treeLeaves
List<Node> tempLeaves = new ArrayList<>(treeLeaves);
for (leaf : tempLeaves ) {
treeLeaves.add(new Node());
}
List treeLeaves=new ArrayList();
//... 在树视图中添加一些内容
List tempLeaves=新的ArrayList(treeLeaves);
用于(叶:模板叶){
添加(新节点());
}
简而言之,在大多数情况下,如果更改集合的结构,所有仍然打开的迭代器都将无效。(相当多的例外,包括使用并发集合,或者通过迭代器进行修改,等等)
您的问题可以通过以下方式轻松演示:
List<Node> treeLeaves = new ArrayList<>();
//... add something to treeLeaves
for (leaf : treeLeaves) {
treeLeaves.add(new Node());
}
List treeLeaves=new ArrayList();
//... 在树视图中添加一些内容
用于(叶:树叶){
添加(新节点());
}
对于您的情况,可以通过创建一个新集合进行迭代来轻松解决:
List<Node> treeLeaves = new ArrayList<>();
//... add something to treeLeaves
List<Node> tempLeaves = new ArrayList<>(treeLeaves);
for (leaf : tempLeaves ) {
treeLeaves.add(new Node());
}
List treeLeaves=new ArrayList();
//... 在树视图中添加一些内容
List tempLeaves=新的ArrayList(treeLeaves);
用于(叶:模板叶){
添加(新节点());
}
对于ArrayList
,只需使用索引即可避免迭代器:
for (int i = 0; i < treeLeaves.size(); i++) {
Tree current = treeLeaves.get(i);
// your code
}
for(int i=0;i
只要你做的事情是追加到数组的末尾,你不插入中间或开始,或者删除任何项目,这将是有效的。code>treeLeaves.size()将在每次执行循环时重新计算,这意味着如果附加到末尾,将重新计算大小,并且
i
将进入新项。是的,使用旧式循环不像迭代器那样“酷”,但它可以工作
除了
ArrayList
之外,我不建议对任何类型的List
使用它,因为一般来说,get(I)
必须从列表的开头开始,逐步遍历每个元素(除非运行时优化了在get(I)之后使用get(I+1)
)
,这不会太难,但我不知道实现是否做到了这一点)。但是,对于ArrayList
,get(i)
应该花费恒定的时间 对于ArrayList
,只需使用索引即可避免迭代器:
for (int i = 0; i < treeLeaves.size(); i++) {
Tree current = treeLeaves.get(i);
// your code
}
for(int i=0;i
只要你做的事情是追加到数组的末尾,你不插入中间或开始,或者删除任何项目,这将是有效的。code>treeLeaves.size()将在每次执行循环时重新计算,这意味着如果附加到末尾,将重新计算大小,并且
i
将进入新项。是的,使用旧式循环不像迭代器那样“酷”,但它可以工作
除了
ArrayList
之外,我不建议对任何类型的List
使用它,因为一般来说,get(I)
必须从列表的开头开始,逐步遍历每个元素(除非运行时优化了在get(I)之后使用get(I+1)
)
,这不会太难,但我不知道实现是否做到了这一点)。但是,对于ArrayList
,get(i)
应该花费恒定的时间 同步列表没有帮助ConcurrentModificationException
意味着对集合的访问不仅仅是多线程的。好的,非常感谢@Ya Wang,我将尝试一下,我会接触到的。这确实很棒,我不再有例外。谢谢。发生的事情实际上与我的解决方案没有什么不同:P COW实际上意味着当你添加到列表中时,它有了一个列表的新副本(而你仍在迭代原始副本)。同步列表没有任何帮助ConcurrentModificationException
意味着对集合的多线程访问。好的,非常感谢@Ya Wang