如何用一个list去更新另一个list

需求

数据展示有一个list,它的泛型是一个实体类,然后我们编辑界面信息,获得了实体类中一个String字段的list,要求如果原list含有该字段的实体,则保留。如果没有,则去掉该实体。如果新加入,则new一个实体添加!

方案

在Java list的API中有两个方法,这里提一下,removeAll()retainAll(),两个方法的参数都是Collection,前者是去掉两个集合中共有的元素,后者是保留两个集合中共有的元素,如果两个集合的泛型是相同的,可以借助于这两个方法来实现这一需求!
但是我们这里泛型不一样,所以只能通过遍历比较来实现了,思路就是:遍历源list,得到该实体类中String字段,如果新list中包含该字段,则新list去掉该字段,否则源list去掉该实体;然后遍历新list,new出实体,添加到源list即可!

实例

实体类Entity

public class Entity{
    private String a;
    private String b;

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a= a;
    }

    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b= b;
    }
}

源list-------entities
新list-------as

for (Iterator<entities> iter = entities.iterator(); iter.hasNext();) {
	Entity entity=iter.next();
		if (as.contains(entity.getA())) {
			as.remove(entity.getA());
		} else {
			iter.remove();
			//entities.remove(entity);
		}
}

for (String a: as) {
	Entity newEntity = new Entity();
	newEntity.setA(a);
	entities.add(newEntity);
}

问题

最开始在遍历源list的时候,直接用的for each循环遍历,然后删除的时候使用entities.remove(entity);,运行报错java.util.ConcurrentModificationException。查找原因,不能在遍历集合的时候,执行该集合的删除等操作!

Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。

所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章