1. 程式人生 > >如何用一個list去更新另一個list

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