Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/207.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 并发修改异常:添加到ArrayList_Java_Android_Exception_Arraylist_Iteration - Fatal编程技术网

Java 并发修改异常:添加到ArrayList

Java 并发修改异常:添加到ArrayList,java,android,exception,arraylist,iteration,Java,Android,Exception,Arraylist,Iteration,问题发生在 Element element = it.next(); 包含该行的代码位于OnTouchEvent for (Iterator<Element> it = mElements.iterator(); it.hasNext();){ Element element = it.next(); if(touchX > element.mX && touchX < element.mX + element.mBitmap.get

问题发生在

Element element = it.next();
包含该行的代码位于
OnTouchEvent

for (Iterator<Element> it = mElements.iterator(); it.hasNext();){
    Element element = it.next();

    if(touchX > element.mX  && touchX < element.mX + element.mBitmap.getWidth() && touchY > element.mY   
            && touchY < element.mY + element.mBitmap.getHeight()) {  

        //irrelevant stuff..

        if(element.cFlag){
            mElements.add(new Element("crack",getResources(), (int)touchX,(int)touchY));
            element.cFlag = false;

        }           
    }
}

我如何才能做到这一点?

在对集合进行迭代时,不允许向集合中添加条目

一个选项是在迭代
melents
时为新条目创建一个新的
列表
,然后将所有新条目添加到
melents
melents.addAll(newElements)
)。当然,这意味着您不会为这些新元素执行循环体-这是一个问题吗

同时,我建议您更新代码以使用:

在使用
迭代器
遍历列表时修改列表(通过添加或删除元素)时发生

试一试

List thingsToBeAdd=new ArrayList();
for(Iterator it=melents.Iterator();it.hasNext();){
Element=it.next();
如果(…){
//无关的东西。。
if(element.cFlag){
//添加(新元素(“裂纹”,getResources(),(int)touchX,(int)touchY));
thingsToBeAdd.add(新元素(“crack”,getResources(),(int)touchX,(int)touchY));
element.cFlag=false;
}           
}
}
添加所有内容(添加内容);

也应考虑乔恩建议的每个循环的增强。

在这个例子中从列表中添加到CME,没有数量的<代码>同步< /代码>会让您避免。相反,考虑使用迭代器添加…

        for(ListIterator<Element> it = mElements.listIterator(); it.hasNext();){
            Element element = it.next();

            if(touchX > element.mX  && touchX < element.mX + element.mBitmap.getWidth() && touchY > element.mY   
                    && touchY < element.mY + element.mBitmap.getHeight()) {  

                //irrelevant stuff..

                if(element.cFlag){
                    // mElements.add(new Element("crack",getResources(), (int)touchX,(int)touchY));
                    it.add(new Element("crack",getResources(), (int)touchX,(int)touchY));
                    element.cFlag = false;

                }           
            }
        }
for(ListIterator it=mElements.ListIterator();it.hasNext();){
Element=it.next();
if(touchX>element.mX&&touchXelement.mY
&&touchY

而且我觉得说这样的话有点滑

…问题发生在
Element=it.next()处

为了精确起见,请注意,以上不保证


指出这种行为不能保证,因为一般来说,在存在非同步并发修改的情况下,不可能做出任何硬保证。Fail fast操作在尽力而为的基础上抛出ConcurrentModificationException。

索引for循环也应该工作

for (int i = 0; i < collection.size(); i++)
for(int i=0;i
使用迭代器还可以修复并发问题,如:

Iterator<Object> it = iterator.next().iterator();
while (it.hasNext()) {
    it.remove();
}
for (Element element : new ArrayList<Element>(mElements)) {
    ...
}
Iterator it=Iterator.next().Iterator();
while(it.hasNext()){
it.remove();
}

我通常使用这样的东西:

Iterator<Object> it = iterator.next().iterator();
while (it.hasNext()) {
    it.remove();
}
for (Element element : new ArrayList<Element>(mElements)) {
    ...
}
for(元素:新ArrayList(mElements)){
...
}
快速、干净、无缺陷


另一种选择是使用CopyOnWriteArrayList,我已经尝试了我的例子中的所有方面,在适配器a列表中进行迭代,但是由于一次又一次地点击,我向我显示了抛出异常的消息。 我试着把名单给

 = (CopyOnWriteArraylist<MyClass>)mylist.value;
我解决了创建锁的问题(Kotlin):


您可以对
循环使用自动减量
,并在下次处理其他元素

List additionalElements = new ArrayList();
for(int i = mElements.size() - 1; i > -1 ; i--){
    //your business
    additionalElements.add(newElement);
}
mElements.add(additionalElements);
公认的解决方案(创建集合副本)通常运行良好

但是,如果
元素
包含另一个集合,则不会生成深度副本

例如:

class Element {
   List<Kid> kids;

   getKids() {
      return kids;
   }
}

实际上,我一开始有一个增强的for循环。我最近使用了一个迭代器,因为我认为这有助于解决问题,但事实并非如此。我相信增强的for循环在后台使用了一个迭代器,因此,使用它应该会导致同样的问题。@OWiz:这两个表单将编译成基本相同的代码。您可能会陷入一个无限循环中。当我必须使用“从列表中删除”时,可能的重复项不起作用,而我每次都必须使用传统的for循环以及对循环中“i”的修改。@AmitTumkur尝试使用“iterator.remove();“代替”列表。删除(对象)“:)但新Arraylist的对象将执行列表的浅层复制,该列表指向同一列表。不,它不会指向同一列表。列表会被复制。但是这不会在一个具有不同项目计数的列表中迭代?我认为,如果从原始列表中删除一个项目,它仍然在复制的ArrayList中,不是吗?显然,修改后的列表中会有不同数量的项目。关键是,您仍然能够迭代所有原始列表项,同时根据需要修改列表。迭代器仅在您希望删除元素时有用,但如果您希望按照本问题的要求将项添加到列表中,迭代器则无效。
import java.util.concurrent.locks.ReentrantLock

Class A {
    private val listLock = ReentrantLock()
    fun doSomething(newElement){
        listLock.lock()
        list.add(newElement)
        listLock.unlock()
    }
}
List additionalElements = new ArrayList();
for(int i = mElements.size() - 1; i > -1 ; i--){
    //your business
    additionalElements.add(newElement);
}
mElements.add(additionalElements);
class Element {
   List<Kid> kids;

   getKids() {
      return kids;
   }
}
for (Element element : new ArrayList<Element>(elements)) { ... }
class Element {
   List<Kid> kids;

   getKids() {
      // Return a copy of the child collection
      return new ArrayList<Kid>(kids);
   }
}