我们说我有一个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来比较和替换....
答案 0 :(得分:4)
对于单线爱好者(running demo):
List<Point> list3 = new ArrayList<Point>(new HashSet<Point>(list1){{ addAll(list2); }});
安全版* (running demo):
Set<String> tmpSet = new HashSet<String>(arrayList1);
tmpSet.addAll(arrayList2);
List<String> mergedList = new ArrayList<String>(tmpSet);
*正如布鲁斯·韦恩正确指出的那样,Double Brace initialization(单行示例,在两个示例中也用于填充前两个列表)应谨慎使用,因为其中描述了潜在的缺点。以下文章:
解释: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
您当前的解决方案可能是错误的(它将跳过一个元素或永远运行,具体取决于您的循环):
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覆盖率)。然后(只有那时!)优化,如果需要!