【问题标题】:Merging two arrayLists into a new arrayList, with no duplicates and in order, in Java在Java中将两个arrayLists合并为一个新的arrayList,没有重复且按顺序排列
【发布时间】:2012-04-12 15:38:42
【问题描述】:

我正在尝试“组合”两个数组列表,生成一个新的数组列表,其中包含两个组合数组列表中的所有数字,但没有任何重复的元素,它们应该是有序的。我想出了下面的这段代码。我浏览了一遍,这对我来说很有意义,但我不确定我是否可以使用 来比较 arrayLists 中的 get(i)。我将array1 中的所有元素添加到plusArray 中。然后我将通过 plusArray 并将其与 array2 进行比较,以查看在 plusArray 中是否存在任何 array2 的元素。如果他们这样做,我什么也不做,但如果他们不这样做,那么我会尝试将其添加到正确的位置。也许我的嵌套 for 循环使用不正确?注意:ArrayLists 是由用户按升序排列的。

     ArrayList<Integer> plusArray = new ArrayList<Integer>();
for(int i = 0; i < array1.size(); i++){
    plusArray.add(array1.get(i));
}

for(int i = 0; i < plusArray.size(); i++){
    for(int j = 0; j < array2.size(); j++){

    if(array2.get(j) < plusArray.get(i)){
        plusArray.add(i,array2.get(j));
    }
    else if(plusArray.get(i).equals(array2.get(j))){
        ;
    }
    else if(array2.get(j) > plusArray.get(i)){
        plusArray.add(i, array2.get(j));
    }

}

更新:我不再收到以下异常。相反,该程序似乎永远运行。我更改了在 条件中添加元素的位置。 /// 当我的数组列表为时,这是我得到的例外: 集合 1:{ 1 2 } 集合 2:{ 1 3 4 }

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.util.Arrays.copyOf(Unknown Source)
at java.util.ArrayList.grow(Unknown Source)
at java.util.ArrayList.ensureCapacityInternal(Unknown Source)
at java.util.ArrayList.add(Unknown Source)
at IntSet.plus(IntSet.java:92)
at IntSetDriver.main(IntSetDriver.java:61)

【问题讨论】:

  • 请发布你得到的异常。

标签: java arraylist


【解决方案1】:

首先删除重复项:

arrayList1.removeAll(arrayList2);

然后合并两个arrayList:

arrayList1.addAll(arrayList2);

最后,如果你愿意,可以对你的 arrayList 进行排序:

collections.sort(arrayList1);

如果您不想对现有列表进行任何更改,请先创建他们的备份列表:

arrayList1Backup = new ArrayList(arrayList1);

【讨论】:

【解决方案2】:

代替您编写的代码,您可以使用ArrayList.addAll() 合并列表,Collections.sort() 对其进行排序,最后遍历生成的 ArrayList 以删除重复项。因此,总复杂度为O(n)+O(n*log(n))+O(n),相当于O(n*log(n))

【讨论】:

  • 我认为这个答案有点误读,因为整个算法没有在 O(n) 中完成。排序可能需要 O(nlogn)。此外,即使 Traversal 是 O(n),从 ArrayList 中删除也可能需要 O(n),因为它需要(最多)n 个元素的副本。
【解决方案3】:
List<String> listA = new ArrayList<String>();

    listA.add("A");
    listA.add("B");

List<String> listB = new ArrayList<String>();

    listB.add("B");
    listB.add("C");

Set<String> newSet = new HashSet<String>(listA);

    newSet.addAll(listB);
List<String> newList = new ArrayList<String>(newSet);

System.out.println("New List :"+newList);

给你 新列表:[A, B, C]

【讨论】:

    【解决方案4】:

    添加 ArrayList1、ArrayList2 并生成单个数组列表 ArrayList3。 现在将其转换为

    Set Unique_set = new HashSet(Arraylist3);
    

    在独特的集合中,您将获得独特的元素。
    注意

    ArrayList 允许重复值。 Set 不允许值重复。 希望您的问题得到解决。

    【讨论】:

    • 尝试学习 Java 集合,它将解决您的大部分需求。
    【解决方案5】:

    Java 8 Stream API 可用于此目的,

    ArrayList<String> list1 = new ArrayList<>();
    
    list1.add("A");
    list1.add("B");
    list1.add("A");
    list1.add("D");
    list1.add("G");
    
    ArrayList<String> list2 = new ArrayList<>();
    
    list2.add("B");
    list2.add("D");
    list2.add("E");
    list2.add("G");
    
    List<String> noDup = Stream.concat(list1.stream(), list2.stream())
                         .distinct()
                         .collect(Collectors.toList());
    noDup.forEach(System.out::println);
    

    顺便提一下,不要忘记distinct() 使用了hashCode()

    【讨论】:

      【解决方案6】:

      这是使用 java 8 的一种解决方案:

      Stream.of(list1, list2)
          .flatMap(Collection::stream)
          .distinct()
          // .sorted() uncomment if you want sorted list
          .collect(Collectors.toList());
      

      【讨论】:

        【解决方案7】:

        也许我的嵌套 for 循环使用不正确?

        提示:嵌套循环不适用于此问题。一个简单的 for 循环也不行。

        您需要将问题可视化。

        在一张纸上写下两个有序列表,然后用两根手指指向各个列表的元素,在头脑中进行合并时逐步浏览它们。然后将您的心理决策过程转化为算法,然后编写代码。

        最佳解决方案只通过两个列表。

        【讨论】:

        • 所以你说的是while循环还是do循环?与不同格式的 for 循环不同
        • 好吧...也许明天再看看这个,事情会变得更清楚。
        • 还有更多提示吗?我不断回到我认为可行的原始解决方案
        【解决方案8】:

        在第一个数组列表中添加元素

        ArrayList<String> firstArrayList = new ArrayList<String>();
        
        firstArrayList.add("A");
        firstArrayList.add("B");
        firstArrayList.add("C");
        firstArrayList.add("D");
        firstArrayList.add("E");
        

        在第二个数组列表中添加元素

        ArrayList<String> secondArrayList = new ArrayList<String>();
        
        secondArrayList.add("B");
        secondArrayList.add("D");
        secondArrayList.add("F");
        secondArrayList.add("G");
        

        在第二个数组列表中添加第一个数组列表的元素

        secondArrayList.addAll(firstArrayList);
        

        分配新的组合数组列表并添加两个数组列表中的所有元素

        ArrayList<String> comboArrayList = new ArrayList<String>(firstArrayList);
        comboArrayList.addAll(secondArrayList);
        

        为从 arraylist 中删除重复条目分配新 Set

        Set<String> setList = new LinkedHashSet<String>(comboArrayList);
        comboArrayList.clear();
        comboArrayList.addAll(setList);
        

        排序数组列表

        Collections.sort(comboArrayList);
        

        输出

         A
         B
         C
         D
         E
         F
         G
        

        【讨论】:

          【解决方案9】:

          你的第二个 for 循环应该有 j++ 而不是 i++

          【讨论】:

          • 我修复了它并放入了新的异常
          【解决方案10】:

          我不确定为什么您当前的代码会失败(您得到的异常是什么?),但我想指出这种方法执行 O(N-squared)。考虑对输入数组进行预排序(如果它们未定义为预排序)并合并已排序的数组:

          http://www.algolist.net/Algorithms/Merge/Sorted_arrays

          排序一般是O(N logN),合并是O(m+n)。

          【讨论】:

          • 我不确定我是否应该使用这种方法,因为我还没有在课堂上学到这一点。不过我想它不会疼吗?
          • 如果讲师教授了一种特定的方法,您可能希望至少实施他所展示的内容。不过,熟悉大 O 的概念以及不同算法的相对性能非常重要。如果您有时间,也可以实施此方法并比较相当大的输入的性能。
          • 好吧,他并没有真正教我们如何做到这一点。他们只是教我们代码,我们必须实现我们所知道的来完成它。身份证
          【解决方案11】:

          你的嵌套 for 循环

           for(int j = 0; j < array2.size(); i++){
          

          是无限的,因为 j 将始终等于 0,另一方面, i 将在此循环中随意增加。当 i 大于 plusArray.size() 时,你会得到 OutOfBoundaryException

          【讨论】:

          • ArrayList.add(x) 在列表末尾添加 x,因此您没有对 ArrayList 进行排序,但您的循环需要对 plusArray 进行排序,对吗?
          • Java API 集合和 ArrayList:docs.oracle.com/javase/1.5.0/docs/api
          • 啊,我明白了。我更改了代码并添加了添加数字的位置
          【解决方案12】:

          您不必手动编码。问题定义正是 Apache Commons CollectionUtils#collate 的行为。它还针对不同的排序顺序进行了重载并允许重复。

          【讨论】:

          • 最佳答案的形式与此完全相同:“不要自己写,这里有一些对象会为你做。”我修改了措辞。
          【解决方案13】:
          **Add elements in Final arraylist,**
          **This will Help you sure**
          
          import java.util.ArrayList;
          import java.util.List;
          
          public class NonDuplicateList {
          
          public static void main(String[] args) {
          
              List<String> l1 = new ArrayList<String>();
              l1.add("1");l1.add("2");l1.add("3");l1.add("4");l1.add("5");l1.add("6");
              List<String> l2 = new ArrayList<String>();
              l2.add("1");l2.add("7");l2.add("8");l2.add("9");l2.add("10");l2.add("3");
              List<String> l3 = new ArrayList<String>();
              l3.addAll(l1);
              l3.addAll(l2);
              for (int i = 0; i < l3.size(); i++) {
                  for (int j=i+1; j < l3.size(); j++) {
                       if(l3.get(i) == l3.get(j)) {
                           l3.remove(j);
                      }
                  }
              }
              System.out.println(l3);
          }
          

          }

          输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

          【讨论】:

          • 不要只是转储代码。请注意解释为什么此解决方案有效。
          【解决方案14】:

          我明白你不想使用内置函数来合并或删除 ArrayList 中的重复项。 您的第一个代码将永远运行,因为外部 for 循环条件是“始终为真”。 由于您正在向 plusArray 添加元素,因此 plusArray 的大小随着每次添加而增加,因此“i”总是小于它。结果,条件永远不会失败,程序永远运行。 提示:尝试先合并列表,然后从合并的列表中删除重复的元素。 :)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-10-28
            • 2016-08-05
            • 2016-07-07
            • 2021-05-01
            • 1970-01-01
            • 2013-10-24
            • 1970-01-01
            相关资源
            最近更新 更多