如何用一個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() 方法會在刪除當前迭代物件的同時維護索引的一致性。