0

I have an ExpandableListView, which has objects of class Group as groups. Each Group object has ArrayList, and the objects in this array are children. When a user clicks on child, it's supposed to do the following:

  • Check if the child's boolean selected set to true or false. True means add it to the array, false - remove it from the array.
  • If true: check if the ID of child's parent (Group) exists in selected_groups_ids array
    • If yes - add selected child object to ArrayList in the Group that is in the array selected_groups.
    • if no - add the ID to array selected_groups_ids, create new empty Group object with the ID of child's parent and add it to the selected_groups array, add the selected child to the ArrayList in that group.
  • If false: remove this child from ArrayList in the Group inside selected_groups
    • Check for ArrayList size
    • If it's 0 - remove the Group object from selected_groups array.

So here's what I tried to do:

This is the Group object code:

public class Group {

private int group_id;
private String group_name;
private ArrayList<Base_Item> group_items = new ArrayList<Base_Item>();

public Group(int category_id, String group_name, ArrayList<Base_Item> items) {
    super();
    this.group_id = category_id;
    this.group_name = group_name;
    this.group_items = items;
}


public Group(int group_id, String group_name) {
    super();
    this.group_id = group_id;
    this.group_name = group_name;
}

// Getters and setters...

public int remove_item_from_array(Base_Item item)
{
    for(Base_Item current_item : group_items)
    {
        if(current_item.getItem_id() == item.getItem_id())
        {
            group_items.remove(current_item);
        }
    }
    return group_items.size();
}

Then in my Activity with the Expandable list:

@Override
        public boolean onChildClick(ExpandableListView parent, View v,
                int groupPosition, int childPosition, long id) {
            Group selected_group = arr_all_groups.get(groupPosition);
            Base_Item bi = selected_group.getGroup_items().get(childPosition);
            Group temp_group = new Group(selected_group.getGroup_id(), selected_group.getGroup_name());

            if(!bi.isBase_item_selected())
            {
                bi.setBase_item_selected(true);
                if(!is_group_in_array(selected_group.getGroup_id()))
                {
                    arr_selected_groups_ids.add(selected_group.getGroup_id());
                    arr_selected_groups.add(temp_group);
                }
                insert_item_to_array(temp_group, bi);
                Log.i("Array size +++", ""+arr_selected_groups.size());

            } else {
                bi.setBase_item_selected(false);
                remove_item_from_array(temp_group, bi);
                Log.i("Array size ---", ""+arr_selected_groups.size());
            }
            adapter.notifyDataSetChanged();

            return false;
        }

private boolean is_group_in_array(int group_id)
{
    for(int i : arr_selected_groups_ids)
    {
        if (i == group_id)
            return true;
    }
    return false;
}

private void insert_item_to_array(Group g, Base_Item bi)
{
    for(Group current_group : arr_selected_groups)
    {
        if(current_group.getGroup_id() == g.getGroup_id())
        {
            ArrayList<Base_Item> arr = current_group.getGroup_items();
            arr.add(bi);
            break;
        }
    }
}

private void remove_item_from_array(Group g, Base_Item bi)
{
    for(Group current_group : arr_selected_groups)
    {
        if(current_group.getGroup_id() == g.getGroup_id())
        {
            int arr_size = current_group.remove_item_from_array(bi);
            if(arr_size==0)
            {
                arr_selected_groups_ids.remove(current_group.getGroup_id());
                arr_selected_groups.remove(current_group);
            }
        }
    }
}

It looks like the objects are being added - I tried several Log records and Toast messages, and each time I was adding a child I was getting the correct size of the array in the Group object. The problem begins when I want to remove the child object from the array or remove the Group from from selected_groups array if the ArrayList in this group is empty. The app crashes with this message:

07-22 11:01:03.734: E/AndroidRuntime(31281): FATAL EXCEPTION: main
07-22 11:01:03.734: E/AndroidRuntime(31281): java.util.ConcurrentModificationException
07-22 11:01:03.734: E/AndroidRuntime(31281):    at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:569)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at com.mycompany.myapp.models.Group.remove_item_from_array(Group.java:67)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at com.mycompany.myapp.activities.Activity_Add_Edit_Trip.remove_item_from_array(Activity_Add_Edit_Trip.java:359)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at com.mycompany.myapp.activities.Activity_Add_Edit_Trip.access$2(Activity_Add_Edit_Trip.java:338)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at com.mycompany.myapp.activities.Activity_Add_Edit_Trip$2.onChildClick(Activity_Add_Edit_Trip.java:114)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at android.widget.ExpandableListView.handleItemClick(ExpandableListView.java:582)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at android.widget.ExpandableListView.performItemClick(ExpandableListView.java:521)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at android.widget.AbsListView$PerformClick.run(AbsListView.java:2514)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at android.widget.AbsListView$1.run(AbsListView.java:3168)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at android.os.Handler.handleCallback(Handler.java:605)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at android.os.Handler.dispatchMessage(Handler.java:92)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at android.os.Looper.loop(Looper.java:137)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at android.app.ActivityThread.main(ActivityThread.java:4424)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at java.lang.reflect.Method.invokeNative(Native Method)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at java.lang.reflect.Method.invoke(Method.java:511)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
07-22 11:01:03.734: E/AndroidRuntime(31281):    at dalvik.system.NativeStart.main(Native Method)

it points to this line in my Group class (line 67):

for(Base_Item current_item : group_items)

and to this line in my Activity (line 359):

int arr_size = current_group.remove_item_from_array(bi);

line 338:

private void remove_item_from_array(Group g, Base_Item bi)

line 114:

remove_item_from_array(temp_group, bi);

Why is it happening? What am I doing wrong here?

2
  • Go for simple for loop instead of foreach. Commented Jul 22, 2014 at 9:34
  • possible duplicate of stackoverflow.com/questions/3184883/… Commented Jul 22, 2014 at 9:57

2 Answers 2

1

You cannot remove an element with the collection.remove() function while using the foreach-loop, only the iterator.remove() function in this fashion, which isn't available to you in this form.

Therefore, the problem is that

for(Group current_group : arr_selected_groups) //you are using this kind of loop
{
    ....
}

For this code to work, use the following, slightly dumber version of iteration:

for(int i = 0; i < arr_selected_groups.size(); i++)
{
    Group current_group = arr_selected_groups.get(i);
    if(current_group.getGroup_id() == g.getGroup_id())
    {
        int arr_size = current_group.remove_item_from_array(bi);
        if(arr_size==0)
        {
            arr_selected_groups_ids.remove(current_group.getGroup_id());
            arr_selected_groups.remove(current_group);
            i--; //once you remove the current element, decrease the index by one

            //you can also use the line arr_selected_groups.remove(i--);
        }
    }
}

You could also use the

Iterator<Group> iterator = arr_selected_groups.iterator();
while(iterator.hasNext())
{
    Group current_group = iterator.next();
    if(current_group.getGroup_id() == g.getGroup_id())
    {
        int arr_size = current_group.remove_item_from_array(bi);
        if(arr_size==0)
        {
            arr_selected_groups_ids.remove(current_group.getGroup_id());
            iterator.remove(); //this method 
        }
    }
}

But I honestly don't prefer it to the first one I mentioned, I think the iterator makes it less clear in case of a list. In the case of a Set, it would be different of course.

Sign up to request clarification or add additional context in comments.

3 Comments

I tried to use the same "dumb" loop in my Group class to remove the Base_Item from the Array, but eventually got this error message: java.lang.IndexOutOfBoundsException: Invalid index 3, size is 2` at this line: arr_selected_groups_ids.remove(current_group.getGroup_id()); So I changed it to: arr_selected_groups_ids.remove(arr_selected_groups_ids.indexOf(current_group.getGroup_id())); and then looks like it worked perfectly! Thank you so very much!!! I was pulling my hair out with this problem...
I'm glad I could help :) On a second glance though, the item removal from group_items in remove_item_from_array() has the same error just waiting around to emerge from the depths. Just a note.
I actually changed it immediately too, according to your explanation. So it had for loop instead of foreach too. Ran a few tests and it worked! Hopefully It will not fail! :) Having other issues now, with other code, but that's a different story... :)
1

you need to use iterator if you want to modify your collection in loop.

Iterator it=list.iterator();
while (it.hasNext()){
    System.out.println(it.next());
    it.remove(); // valid here
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.