如何将arrayList2中不存在的值添加到arrayList1?

时间:2015-05-27 12:11:55

标签: java arraylist set array-merge no-duplicates

我们说我有一个PointsList1的Points。数据结构如下:

(1,2)->(2,2)->(3,2)->(4,2)->(5,2)

我有另一个PointsList2点:

(2,2)->(1,2)->(8,5)->(9,3)

如何比较两个列表并将arrayList2中不存在的值添加到arrayList1?

当前解决方案

我现在能想到的唯一方法是使用for循环来比较arrayList1中的每个Points,例如if(!arrayList1.contains(arrayList2.get(i))){ arrayList1.add(arrayList2.get(i)); } i++;

是否有更有效的方法或已经准备好的课程方法?因为我有arrayList1直到arrayList6来比较和替换....

7 个答案:

答案 0 :(得分:4)

  1. 对于单线爱好者running demo):

    List<Point> list3 = new ArrayList<Point>(new HashSet<Point>(list1){{ addAll(list2); }});
    
  2. 安全版* running demo):

    Set<String> tmpSet = new HashSet<String>(arrayList1);
    tmpSet.addAll(arrayList2);
    List<String> mergedList = new ArrayList<String>(tmpSet);
    

    *正如布鲁斯·韦恩正确指出的那样,Double Brace initialization(单行示例,在两个示例中也用于填充前两个列表)应谨慎使用,因为其中描述了潜在的缺点。以下文章:

      

    Don’t be “Clever”: The Double Curly Braces Anti Pattern

  3. 解释Set s不能包含重复项,因此请使用一个作为转换向量。

    示例1代码:

    List<String> arrayList1 = new ArrayList<String>(){{ add("One"); add("Two");   }};
    List<String> arrayList2 = new ArrayList<String>(){{ add("Two"); add("Three"); }};   
    List<String> mergedList = new ArrayList<String>(new HashSet<String>(arrayList1){{ addAll(arrayList2); }});
    System.out.println(mergedList);
    
      

    输出:[一,二,三]

    示例2代码:

    List<String> arrayList1 = new ArrayList<String>(){{ add("One"); add("Two");   }}; 
    List<String> arrayList2 = new ArrayList<String>(){{ add("Two"); add("Three"); }}; 
    Set<String> tmpSet = new HashSet<String>(arrayList1);
    tmpSet.addAll(arrayList2);
    List<String> mergedList = new ArrayList<String>(tmpSet);
    System.out.println(mergedList);
    
      

    输出:[一,二,三]

答案 1 :(得分:2)

如果时间复杂度是您的主要优先级,请将List1中的所有积分添加到HashSet<Point>

然后,对于之后的每个列表,遍历它并查看该集合是否包含每个点,如果没有,则将其添加到List1

Set<Point> pointsInList1 = new HashSet<>(list1);
for(Point p : list2)
{
    if(!pointsInList1.contains(p)) {
        list1.add(p);
        pointsInList1.add(p);
    }
}

//Repeat for other lists

此解决方案与最大列表的大小呈线性关系。

答案 2 :(得分:1)

您应该使用Import-Module Group Policy。这是一个没有重复的集合。所以你可以两次添加相同的值,它只会出现一次。

这意味着您可以在Set中添加多个List,其中不会有重复项。

Set

输出:

    Set setA = new HashSet(); 

    ArrayList<Point> points1 = new ArrayList<Point>();
    ArrayList<Point> points2 = new ArrayList<Point>();

    Point element1 = new Point(0,0);
    Point element2 = new Point(0,1);
    Point element3 = new Point(0,0);
    Point element4 = new Point(0,2);

    points1.add(element1); 
    points1.add(element2); 
    points1.add(element3);

    points2.add(element1);
    points2.add(element4);

    setA.addAll(points1);
    setA.addAll(points2);

    Iterator<Point> it = setA.iterator();
    while(it.hasNext())
        System.out.println(it.next());

答案 3 :(得分:1)

它可以有多种解决方案。当您使用已java.awt.Point方法覆盖的equals类时(基于坐标)。 因此,您可以轻松使用contains类的List方法。

for(Point point : list2){
     if(!list1.contains(point)){
         list1.add(point);
     }
}

确保使用for each循环以获得更好的性能(不要使用基于索引的循环(如果您使用LinkedList会有所不同))。

ii)另一种方法是使用java.util.Set并使用其方法addAll(Set)。由于Set并非全部重复,因此会有效地合并元素。

答案 4 :(得分:0)

你可以做这样的事情

    list2.removeAll(list1);
    list1.addAll(list2);

答案 5 :(得分:0)

你必须在Point Class

中覆盖你的同等功能

然后你可以迭代这两个列表,并比较它们的值。

答案 6 :(得分:0)

  

如何比较两个列表

那个很容易,只需使用equals。

  

将arrayList2中不存在的值添加到arrayList1

  • 从arrayList2中删除arrayList1的所有元素并将其添加到arrayList2。这样只会将新元素添加到arrayList2
  • 获取差异(arrayList1 - arrayList2)并将这些添加到arrayList2(例如使用CollectionUtils

您当前的解决方案可能是错误的(它将跳过一个元素或永远运行,具体取决于您的循环):

if(arrayList1.contains(arrayList2.get(i))) {
  i++; // this shouldn't be there if done in the loop
} else {
  arrayList1.add(arrayList2.get(i)); // here a ++ is needed if not in the loop
}
  

是否有更有效的方式

一点建议:
首先,让它工作(并具有良好的UnitTest覆盖率)。然后(只有那时!)优化,如果需要!