簡體   English   中英

刪除兩個不同的Arraylist之間的公共元素

[英]Removing common elements between two different Arraylist

我已經閱讀了幾篇關於此的文章,但沒有得到我想要的確切信息。 我知道如何為此開發復雜的邏輯,這是針對Android的,由於可用資源有限,我們不能期望在設備上進行過多的處理。

我有一個由五個字段組成的Bean類對象的ArrayList作為

Java Bean-MyShares

  1. 文檔名稱
  2. 文件路徑
  3. 文件大小
  4. isShared
  5. 創作者

我還有另一個僅包含文件路徑的String ArrayList。 現在,我要刪除兩個arraylist之間的所有公共元素,這意味着以秒為單位的arraylist的文件路徑和第一個arraylist對象中的文件路徑相似,那么我必須從兩個arraylist中都刪除,但是我不希望有一個新的arraylist其中包含不常見的元素。 但是我只想獲取沒有它們共同元素的兩個arraylist。

您可以使用從String Map到您的對象類型(我使用Obj來創建SSCCE)。

假設給了我們一個列表objects和一個列表strings

腳步:

  1. 將所有objects以其str變量為鍵放置在map
  2. 使用map.keySet()獲取所有這些str變量
  3. 通過keys.removeAll(strings)獲取objects所有但不是stringskeys.removeAll(strings)
  4. 通過strings.removeAll(keys)獲取所有在strings但不在objectsstrings.removeAll(keys)
  5. 獲取與其余keys對應的objects

請注意,在第3步和第4步中需要小心,因為您需要備份其中一個集合。

import java.util.*;

public class Test { 
    public static void main(String[] args) throws Exception {
        new Test();
    }

    public Test() {
        List<Obj> objects = new ArrayList<>();
        objects.add(new Obj("a"));
        objects.add(new Obj("b"));
        objects.add(new Obj("c"));

        List<String> strings = new ArrayList<>();
        strings.add("a");
        strings.add("d");
        strings.add("e");

        remove(objects, strings);

        System.out.println(objects);
        System.out.println(strings);
    }

    public void remove(List<Obj> objects, List<String> strings) {
        Map<String, Obj> map = new HashMap<>();
        for (Obj object : objects) {
            map.put(object.str, object);
        }

        Set<String> keys = map.keySet();
        List<String> oldStrings = new ArrayList<>(strings);

        strings.removeAll(keys);
        keys.removeAll(oldStrings);

        objects.clear();
        for (String key: keys) {
            objects.add(map.get(key));
        }       
    }

    public class Obj {  
        public String str;
        public Obj(String str) {
            this.str = str;
        }
        @Override
        public String toString() {
            return str;
        }       
    }
}

印刷品:

[b, c]
[d, e]

我會為你提供一些線索

假設您有兩個列表,一個用於bean對象,即myBeans ,另一個用於filePaths,即filePaths。

List<MyBean> beansToRemove = new ArrayList<MyBean>();
List<FilePath> filePathsToRemove = new ArrayList<FilePath>();

for(Bean myBean : myBeans) {
    for(FilePath filePath : filePaths) {
        if(myBean.getfilePath.equals(filePath.getFilePath())) {
            beansToRemove.add(myBean);
            filePathsToRemove.add(filePath);
        }
    }
}

//Now remove filePaths and beans if any

for(Bean myBean : beansToRemove) {
    myBeans.remove(myBean);
}

for(FilePath filePath : filePathsToRemove) {
    filePaths.remove(filePath);
}

這只是讓您清楚該做什么的流程; 您可以根據需要進一步自定義它。

您可以使用一個外部循環來掃描Bean對象,並使用一個內部循環來掃描文件路徑。

偽代碼:

for (Bean i in beans) {
    for (String p in paths) {
        if (i.path.equals(p)) {
            beansToRemove.add(i);
            pathsToRemove.add(p);
        }
    }
}
beans.removeAll(beansToRemove);
paths.removeAll(pathsToRemove);

我不確定跟蹤剩余陣列列表的額外陣列列表是否與您的問題背道而馳,因為原始陣列仍然存在。 如果您對路徑上的兩個數組進行預排序並跟蹤每個區域中的位置(不是詳盡搜索),則可以將其從n2改進為nlgn

粗糙的Java代碼:

HashSet<String> commonKeys = new HashSet();
for (Share share : shares) {
    commonKeys.add(share.filePath);
}
commonKeys.retainAll(filePaths);
for (Iterator<Share> it = shares.iterator(); it.hasNext(); ) {
    Share share = it.next();
    if (commonKeys.contains(share.filePath)) {
        it.remove();
    }
}
filePaths.removeAll(commonKeys);

這不會是O(N)因為在ArrayList上進行remove非常昂貴。 要獲得O(N)行為,您要么需要創建新的ArrayList實例,要么將您不想刪除的元素添加到臨時列表中,然后執行clear()並將它們重新添加到原始列表中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM