1

我已经为此阅读了几篇文章,但没有得到我正在寻找的确切内容。我知道如何为此开发一个复杂的逻辑,这是针对 Android 的,由于可用资源有限,我们不能指望设备上有太多的处理。

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

Java Bean -- MyShares

  1. 文件名
  2. 文件路径
  3. 文件大小
  4. 是共享的
  5. 创作者

我有另一个仅包含文件路径的字符串 ArrayList。现在我想要的是删除两个数组列表之间的所有公共元素意味着以秒为单位的文件路径数组列表和第一个数组列表对象中的文件路径相似然后我必须从两个数组列表中删除但我不想要一个新的数组列表其中包含不常见的元素。但我只想在没有共同元素的情况下获得我的两个数组列表。

4

4 回答 4

2

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

于 2013-04-11T13:11:34.233 回答
2

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

假设我们得到一个 listobjects和一个 list strings

脚步:

  1. 将所有变量放入objectsa 中map,并将其str变量作为键
  2. 使用获取所有这些str变量map.keySet()
  3. 获取所有 inobjects但不在stringsby中的字符串keys.removeAll(strings)
  4. 获取所有 instrings但不在objectsby中的字符串strings.removeAll(keys)
  5. 获取objects对应于剩余的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]
于 2013-04-11T13:14:42.967 回答
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);
}

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

于 2013-04-11T13:29:57.330 回答
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);

我不确定我的额外数组列表是否会跟踪已删除的数组列表是否违反您的问题,因为原始数组仍然存在。如果您对路径上的两个数组进行预排序并跟踪每个区域中的位置(不是详尽搜索),您可以将其从 n2 改进为 nlgn

于 2013-04-11T13:07:41.573 回答