简体   繁体   English

根据arraylist元素之间的特定比较,删除自定义对象类型的arraylist的内容

[英]Removing the contents of an arraylist of customized object type based on a specific comparison between the elements of the arraylist

I have an ArrayList of type RemoveTest, where RemoveTest is a user defined class. 我有一个类型为RemoveTest的ArrayList,其中RemoveTest是用户定义的类。 RemoveTest has two properties of String type mId and rmId. RemoveTest具有字符串类型mId和rmId的两个属性。 I need to find in the ArrayList, elements(Objects of type RemoveTest) satisfying the below criteria: such that the value of obj1.rmId() is same as obj2.getmId() and then remove both of these elements(obj1 and obj2). 我需要在ArrayList中找到满足以下条件的elements(RemoveTest类型的对象):这样obj1.rmId()的值与obj2.getmId()相同,然后删除这两个元素(obj1和obj2) 。

I tried this by writing the below code: 我通过编写以下代码尝试了此操作:

import java.util.ArrayList;
import java.util.Iterator;

public class RemoveItr {

    public static void main(String[] args){
        ArrayList<RemoveTest> eleList = new ArrayList<RemoveTest>();
        RemoveTest obj1 = new RemoveTest();
        obj1.setmId("m1");
        obj1.setRmId("");
        RemoveTest obj2 = new RemoveTest();
        obj2.setmId("m2");
        obj2.setRmId("m1");
        RemoveTest obj3 = new RemoveTest();
        obj3.setmId("m3");
        obj3.setRmId("");
        RemoveTest obj4 = new RemoveTest();
        obj4.setmId("m4");
        obj4.setRmId("m3");
        RemoveTest obj5 = new RemoveTest();
        obj5.setmId("m5");
        obj5.setRmId("");
        eleList.add(obj1);
        eleList.add(obj2);
        eleList.add(obj3);
        eleList.add(obj4);
        eleList.add(obj5);
        Iterator<RemoveTest> i = eleList.iterator();
        while(i.hasNext()){
            RemoveTest fwdM =(RemoveTest)i.next();
            String fwdId = fwdM.getmId();
            Iterator<RemoveTest> ni = eleList.iterator();

            while(ni.hasNext()){
                RemoveTest revM =(RemoveTest)ni.next();
                String revId = revM.getRmId();
                if(fwdId.equals(revId)){
                    System.out.println("fwdId "+fwdId+"- revId "+revId);
                     i.remove();
                     ni.remove();

                }

            }
        }
    }
}

public class RemoveTest {

    String mId;
    String rmId;

    public String getmId() {
        return mId;
    }
    public void setmId(String mId) {
        this.mId = mId;
    }
    public String getRmId() {
        return rmId;
    }
    public void setRmId(String rmId) {
        this.rmId = rmId;
    }

    }

Note: both classes are Public as they were not in the same source file. 注意:这两个类都是公共类,因为它们不在同一个源文件中。

But, I got ConcurrentModificationException and I believe it is because, that as I was already in the middle of iterating through the arraylist, and then other loop(iterator) steps in and tries to operate on the same ArrayList. 但是,我得到了ConcurrentModificationException,我相信这是因为,因为我已经在遍历arraylist的中间,然后其他loop(iterator)介入并尝试在同一ArrayList上进行操作。

Is this understanding correct? 这种理解正确吗? and If so, how can I resolve this problem and achieve the solution. 如果是这样,我该如何解决此问题并实现解决方案。

You can't modify a collection while iterating over it, except by using Iterator.remove() . 迭代时不能修改集合,除非使用Iterator.remove()

This rule implies that you can't use two iterators simultaneously and expect remove() to work, because calling remove() on one iterator will violate the rule for the other iterator. 此规则意味着您不能同时使用两个迭代器并期望remove()起作用,因为在一个迭代器上调用remove()将违反另一个迭代器的规则。

The solution is to collect all the entries that need deleting in a separate Set , then after your logic has completed, call List.removeAll(set) . 解决方案是将所有需要删除的条目收集到一个单独的Set ,然后在逻辑完成之后调用List.removeAll(set)

Given this, you don't need iterators at all - just use the foreach syntax: 鉴于此,您根本不需要迭代器-只需使用foreach语法即可:

For a simplistic example: 举一个简单的例子:

List<RemoveTest> list = new ArrayList<RemoveTest>();
// populate list
Set<RemoveTest> removals = new HashSet<RemoveTest>();
for (RemoveTest i : list)
    for (RemoveTest j : list)
        if (...)
            removals.add(i); // j will get added in another iteration
list.removeAll(removals);

使用CopyOnWriteArrayList而不是ArrayList,它应该可以解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM