删除两个不同的Arraylist之间的共同元素

时间:2013-04-11 12:54:01

标签: java android arraylist

我已经阅读了几篇帖子,但没有得到我想要的确切内容。我知道如何为此开发一个复杂的逻辑,这适用于Android,由于资源有限,我们不能指望在设备上进行太多处理。

我有一个bean类对象的ArrayList,包含五个字段

Java Bean - MyShares

  1. 文件名
  2. 文件路径
  3. 档案大小
  4. isShared
  5. 创建者
  6. 我有另一个String的ArrayList,它只包含文件路径。现在我想要的是删除两个arraylist之间的所有常见元素意味着文件路径在几秒钟arraylist和第一个arraylist对象中的文件路径相似然后我必须从两个arraylist中删除但我不想要一个新的arraylist其中包含不常见的元素。但是我想在没有共同元素的情况下得到我的两个arraylist。

4 个答案:

答案 0 :(得分:2)

您可以使用Map String到您的对象类型(我使用Obj来制作SSCCE)。

假设我们获得了一个列表objects和一个列表strings

步骤:

  1. 将所有objects放入map,其str变量为关键
  2. 使用str
  3. 获取所有map.keySet()个变量
  4. 获取objects但不在strings keys.removeAll(strings)之内的所有字符串<{1}}
  5. 获取strings但不在objects strings.removeAll(keys)之内的所有字符串<{1}}
  6. 获取与剩余objects
  7. 对应的keys

    请注意,您需要在步骤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]
    

答案 1 :(得分:2)

我会为你提供一些线索

假设您有一个用于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);
}

这只是让你清楚做什么的流程;您可以根据需要进一步定制。

答案 2 :(得分:1)

您可以使用外部循环扫描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);

我不确定追踪被删除的arraylists的额外arraylists是否违反你的问题,因为原始阵列仍然存在。 如果你在路径上预先分配两个数组并跟踪每个区域的位置(不是详尽的搜索),你可以将它从n2改为nlgn

答案 3 :(得分:1)

粗糙的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),因为remove上的ArrayList代价很高。要获得O(N)行为,您需要创建新的ArrayList实例,或者将您不想删除的元素添加到临时列表,然后clear()并将它们添加回原始列表