从ArrayList中删除对象

时间:2014-07-22 09:25:45

标签: android arrays arraylist

我有一个ExpandableListView,它将类Group的对象作为组。每个Group对象都有ArrayList,此数组中的对象是子对象。当用户点击孩子时,它应该执行以下操作:

  • 检查孩子的布尔selected是否设置为true或false。 True表示将其添加到数组中,false - 将其从数组中删除。
  • 如果为true:检查子组件父组(组)的ID是否存在于selected_groups_ids数组中
    • 如果是 - 将所选子对象添加到阵列selected_groups中的组中的ArrayList。
    • 如果不是 - 将ID添加到数组selected_groups_ids,使用子父的ID创建新的空Group对象并将其添加到selected_groups数组,将所选子项添加到该组中的ArrayList。
  • 如果为false:从selected_groups内的组中的ArrayList中删除此子项
    • 检查ArrayList大小
    • 如果它为0 - 从selected_groups数组中删除组对象。

所以这就是我尝试做的事情:

这是组对象代码:

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();
}

然后在我的活动中使用可扩展列表:

@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);
            }
        }
    }
}

看起来正在添加对象 - 我尝试了几个日志记录和Toast消息,每次我添加一个子节点时,我都在Group对象中获得了正确的数组大小。如果我想从数组中删除子对象,或者如果此组中的ArrayList为空,则从selected_groups数组中删除组,问题就开始了。该应用程序因此消息崩溃:

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)

它指向我的Group类中的这一行(第67行):

for(Base_Item current_item : group_items)

和我的活动中的这一行(第359行):

int arr_size = current_group.remove_item_from_array(bi);
第338行:

private void remove_item_from_array(Group g, Base_Item bi)

第114行:

remove_item_from_array(temp_group, bi);

为什么会这样?我在这里做错了什么?

2 个答案:

答案 0 :(得分:1)

使用foreach-loop时,不能使用collection.remove()函数删除元素,只能以这种方式使用iterator.remove()函数,这在此表单中不可用。

因此,问题在于

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

要使此代码生效,请使用以下稍微繁琐的迭代版本:

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--);
        }
    }
}

您也可以使用

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 
        }
    }
}

但老实说,我不喜欢它,而不是我提到的第一个,我认为迭代器在列表的情况下不太清楚。在Set的情况下,当然会有所不同。

答案 1 :(得分:1)

如果您希望循环收集iterator,则需要使用modify

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