0

I trying to debug few code and gives Concurrent modification exception

code

final GestureLibrary store1 = GestureLibraries.fromFile(new File(Environment.getExternalStorageDirectory(), "Gesture_launcher"));

     if (store1.load()) 
     {
        for (String name : store1.getGestureEntries()) 
        {
             for (Gesture gesture : store1.getGestures(name)) 
             {
                 if(name.contains(gesture_name))
                 {
                     store1.removeGesture(name, gesture);
                     store1.addGesture(name, mGesture);
                     store1.save();

                     Toast.makeText(getApplicationContext(), getResources().getString(R.string.saved), Toast.LENGTH_LONG).show();
                 }
             }
        }
     }

Executing the above statement gives concurrentModificationException

Logcat

03-28 02:47:45.422: E/AndroidRuntime(449): FATAL EXCEPTION: main
03-28 02:47:45.422: E/AndroidRuntime(449): java.util.ConcurrentModificationException
03-28 02:47:45.422: E/AndroidRuntime(449):  at java.util.HashMap$HashIterator.nextEntry(HashMap.java:796)
03-28 02:47:45.422: E/AndroidRuntime(449):  at java.util.HashMap$KeyIterator.next(HashMap.java:823)
03-28 02:47:45.422: E/AndroidRuntime(449):  at com.likith.gesturebuilder.change_gestures.setGestures(change_gestures.java:69)
03-28 02:47:45.422: E/AndroidRuntime(449):  at com.likith.gesturebuilder.change_gestures$1.onClick(change_gestures.java:110)
03-28 02:47:45.422: E/AndroidRuntime(449):  at android.view.View.performClick(View.java:2485)
03-28 02:47:45.422: E/AndroidRuntime(449):  at android.view.View$PerformClick.run(View.java:9080)
03-28 02:47:45.422: E/AndroidRuntime(449):  at android.os.Handler.handleCallback(Handler.java:587)
03-28 02:47:45.422: E/AndroidRuntime(449):  at android.os.Handler.dispatchMessage(Handler.java:92)
03-28 02:47:45.422: E/AndroidRuntime(449):  at android.os.Looper.loop(Looper.java:123)
03-28 02:47:45.422: E/AndroidRuntime(449):  at android.app.ActivityThread.main(ActivityThread.java:3683)
03-28 02:47:45.422: E/AndroidRuntime(449):  at java.lang.reflect.Method.invokeNative(Native Method)
03-28 02:47:45.422: E/AndroidRuntime(449):  at java.lang.reflect.Method.invoke(Method.java:507)
03-28 02:47:45.422: E/AndroidRuntime(449):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
03-28 02:47:45.422: E/AndroidRuntime(449):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
03-28 02:47:45.422: E/AndroidRuntime(449):  at dalvik.system.NativeStart.main(Native Method)

Please tell any method on how to avoid this exception Thank you

EDIT 1: Now I have modified the code

List<Gesture> list = store1.getGestures(gesture_name);
         Set<String> List_name = store1.getGestureEntries();

         for (String name : List_name) 
         {
             for (Gesture gesture : list) 
             {
                 if(name.contains(gesture_name))
                 {
                     store1.removeGesture(name, gesture);
                     store1.addGesture(name, mGesture);
                     store1.save();

                     Toast.makeText(getApplicationContext(), getResources().getString(R.string.saved), Toast.LENGTH_LONG).show();
                 }
             }
        }

Again it gives me the same error .

Flexicoder
  • 8,251
  • 4
  • 42
  • 56
likith sai
  • 527
  • 1
  • 6
  • 21

2 Answers2

2

You're looping through store1.getGestures() at the same time you're calling store1.removeGesture() and store1.addGesture().

Try copying the gesture array and loop over the copy.

Array<Gesture> newArray = new Array<>();
newArray.addAll(store1.getGestures(name));
for (Gesture gesture : newArray) 
         {
             if(name.contains(gesture_name))
             {
                 store1.removeGesture(name, gesture);
                 store1.addGesture(name, mGesture);
                 store1.save();
...
Quicksilver002
  • 735
  • 5
  • 12
0

An easy way to avoid concurrent modification exceptions is to use a regular for loop.

When using ehanced for loops, an iterator is used. While using the iterator, you are not allow to modify the collection.

A regular for loop looks like this

List<String> list;

for(int i = 0; i < list.size(); i++) {
    String string = list.get(i);
    //use string
}

As opposed to using an enhanced for loop, which looks like this

List<String> list;

for(String string : list) {
     //use string
}
Vince
  • 14,470
  • 7
  • 39
  • 84