从两个Arraylist获取常见记录的最有效方法

时间:2017-11-10 11:14:10

标签: arrays list collections hashmap hashset

我有2个列表

ArrayList<String> l1 = new ArrayList<String>();
    l1.add("ABCD");

    l1.add("DEF");
    l1.add("GHI");
    l1.add("JKL");
    l1.add("MNO");
    l1.add("PQR");
    l1.add("MNO");

    ArrayList<String> l2 = new ArrayList<String>();
    l2.add("ABC");
    l2.add("DEF");
    l2.add("GHI");
    l2.add("PQR");
    l2.add("STU");
    l2.add("ABC");

数据也可以是数百万,我只想知道哪种方法最有效。

1.Solution-1

public ArrayList getCommonWords(ArrayList list1,             ArrayList list2)

{

    ArrayList<String> commonlist = new ArrayList<String>();
    int i = 0;
    while (i < list1.size()) {
        for (int j = 0; j < list2.size(); j++) {
            if (list1.get(i) == list2.get(j)) {
                commonlist.add(list1.get(i));
                break;
            }

        }
        i++;
    }
    return commonlist;

}

解决方案2 - 使用保留功能

是否有其他解决方案相同的...类似哈希等...如果能更有效吗?

1 个答案:

答案 0 :(得分:0)

有几种方法。你只需要决定哪一个更重要:速度或记忆。

优化速度(O(N)运行时复杂度,O(N)内存复杂度):

您可以为其中一个数组使用哈希集。 HashSet中查找/包含的预期复杂度为O(1),平均值取决于桶的数量(b),即O(b / N)。

{
   List <String> common = new ArrayList<>();
   HashSet<String> hs = new HashSet<>();
   hs.addAll(l1); // add all the items from l1 to the hashset    
   for (String s : l2) {
     if hs.contains(s) {
       common.add(s);
     }
   }
}

如果你想优化内存,那么你就不必分配额外的内存,你可以用O(N * M)来做(假设l1和l2不具有相同的大小)和O(1)在记忆中。

List <String> common = new ArrayList<>();
for (String s : l1) {
  if l2.contains(s) {
    common.add(s);
  }
}

您提出的此解决方案与我的第二个解决方案相同。

在比较java中的对象时,不应该使用==。检查对象是否具有相同的引用。请改用equals来检查它们是否具有相同的内容。