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

Java 如何将中不存在的值从arrayList2添加到arrayList1?,java,arraylist,set,array-merge,no-duplicates,Java,Arraylist,Set,Array Merge,No Duplicates,假设我有一个点的ArrayList。数据结构如下所示: (1,2)->(2,2)->(3,2)->(4,2)->(5,2) 我还有另外一个ArrayList 2: (2,2)->(1,2)->(8,5)->(9,3) 如何比较这两个列表并将不存在的值从arrayList2添加到arrayList1 当前解决方案 我现在能想到的唯一方法是使用for循环来比较arrayList1中的每个点,例如,if(!arrayList1.contains(arrayList2.get(I)){arrayList

假设我有一个点的ArrayList。数据结构如下所示:

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

我还有另外一个ArrayList 2:

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

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

当前解决方案

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


是否有一种更有效的方法或已经准备好的方法来自类?因为我有ArrayList 1到ArrayList 6来比较和替换…

您应该使用
集合。这是一个没有重复的集合。因此,您可以将相同的值添加两次,它将只显示一次

这意味着您可以在
集合中添加许多
列表
,其中不会有重复项

    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());

你可以这样做

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

您必须重写Point类中的equal函数

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

如何比较这两个列表

那一个很简单,只要用相等的

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

  • 从ArrayList 2中删除ArrayList 1的所有元素并将其添加到ArrayList 2中。这样,只有新元素才会添加到ArrayList 2中
  • 获取差异(arrayList1-arrayList2)并将其添加到arrayList2(例如,使用)
您当前的解决方案可能是错误的(它将跳过一个元素或永远运行,具体取决于您的循环):

有没有更有效的方法

一点建议:

首先,让它工作(并有一个良好的单元测试覆盖率)。然后(只有那时!)根据需要进行优化

如果时间复杂性是您的主要优先级,请将
列表1
中的所有点添加到
哈希集

然后,对于此后的每个列表,循环查看集合是否包含每个点,如果不包含,则将其添加到
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
Set pointsInList1=新哈希集(list1);
对于(p点:列表2)
{
如果(!pointsInList1.contains(p)){
清单1.添加(p);
点列表1.添加(p);
}
}
//对其他列表重复此操作

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

它可以有多个解决方案。当您使用
java.awt.Point
类时,该类已经覆盖了
equals
方法(基于坐标)。 因此,您可以轻松地使用
列表
类的
包含
方法

for(Point point : list2){
     if(!list1.contains(point)){
         list1.add(point);
     }
}
确保对每个
循环使用
,以获得更好的性能(不要使用基于索引的循环(如果使用的是
LinkedList
),则会产生不同)

ii)另一种选择是使用
java.util.Set
并使用其方法
addAll(Set)
。As集合不会复制所有元素,因此将有效合并元素

  • 专为一线恋人设计的():

    list3=newarraylist(newhashset(list1){{{addAll(list2);}});
    
  • 安全版本*():

    Set tmpSet=newhashset(arrayList1);
    tmpSet.addAll(arrayList2);
    List mergedList=newarraylist(tmpSet);
    
    *正如Bruce Wayne正确指出的,(一行代码示例,也用于两个示例中填充前两个列表),由于以下文章中描述的潜在缺陷,应谨慎使用:

  • 解释
    集合
    s不能包含重复项,因此使用一个作为过渡向量

    示例1代码:

    List arrayList1=new ArrayList(){{add(“一”);add(“两”);};
    List arrayList2=new ArrayList(){{add(“两”);add(“三”);};
    List mergedList=newarraylist(newhashset(arrayList1){{{addAll(arrayList2);}}});
    System.out.println(合并列表);
    
    输出:[1,2,3]

    示例2代码:

    List arrayList1=new ArrayList(){{add(“一”);add(“两”);};
    List arrayList2=new ArrayList(){{add(“两”);add(“三”);};
    Set tmpSet=newhashset(arrayList1);
    tmpSet.addAll(arrayList2);
    List mergedList=newarraylist(tmpSet);
    System.out.println(合并列表);
    
    输出:[1,2,3]


    @Ouney是的,我正在使用这个类:它将修改所有其他列表,我不确定OP是否需要它。我只是将它添加到我的注释中。这与我当前的解决方案是否相同或稍微简单一点?只是你在使用
    HashSet
    foreach
    循环?你基本上是在浏览每个列表,比较每个节点,如果它不存在,就添加它,对吗?@Mark,你的解决方案的时间复杂度(从我从片段中可以推断)是二次的或O(m x n),其中m和n是两个列表的大小。通过使用
    散列集
    ,您可以用时间复杂度换取空间,检查
    列表1中是否存在
    现在是一个O(1)操作。因此,总体时间复杂度是线性的。for-each循环如何实现更好、显著的性能?基本上,算法和我当前的解决方案是一样的,对吗?将列表2中的每个节点与列表1进行比较,如果它在列表1中不存在,则将其添加到列表1中,对吗?它与arrayList没有任何区别,因为它是索引的。所以,get(i)取O(1)。但在linkedList中,get(i)是O(i)操作,因为它必须遍历。因此,如果您使用基于索引的循环,每次调用get(i)时,它都将从0开始并扫描,但对于for each,它使用一个迭代器,该迭代器保存对当前元素的引用,而不是从0开始。是的,你也在做同样的事情,但是
    Set<Point> pointsInList1 = new HashSet<>(list1);
    for(Point p : list2)
    {
        if(!pointsInList1.contains(p)) {
            list1.add(p);
            pointsInList1.add(p);
        }
    }
    
    //Repeat for other lists
    
    for(Point point : list2){
         if(!list1.contains(point)){
             list1.add(point);
         }
    }