How do I add non-existent values from arrayList2 to arrayList1?
Let's say I have an array of List1 of Points. The data structure is as follows:
(1,2)->(2,2)->(3,2)->(4,2)->(5,2)
I have another arrayList2 of points:
(2,2)->(1,2)->(8,5)->(9,3)
How do I compare two lists and add nonexistent values from arrayList2 to arrayList1?
current decision
The only technique I can think of right now is to use a for loop to compare each of the points in arrayList1, for example if(!arrayList1.contains(arrayList2.get(i))){ arrayList1.add(arrayList2.get(i)); } i++;
.
Is there a more efficient way or an already prepared method from the class? Because I have arrayList1 until arrayList6 compares and replaces ....
source to share
-
For lovers of one liner ( demo version ):
List<Point> list3 = new ArrayList<Point>(new HashSet<Point>(list1){{ addAll(list2); }});
-
Safe version * ( demo version ):
Set<String> tmpSet = new HashSet<String>(arrayList1); tmpSet.addAll(arrayList2); List<String> mergedList = new ArrayList<String>(tmpSet);
* As Bruce Wayne correctly pointed out, Initializing a Double Marriage (a single-layer example, also used in both examples to populate the first two lists) should be used with caution due to the potential drawbacks described in the following article:
Explanation : Set
cannot contain duplicates, so use it as a transition vector.
Example 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);
Output : [One, Two, Three]
Example 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);
Output : [One, Two, Three]
source to share
If time complexity is your top priority, add all points in List1
in HashSet<Point>
.
Then, for each list, then skip it and see whether the set of each point, and if not, add it 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
This decision is linear with respect to the size of the largest list.
source to share
You must use Set
. It is a collection without duplicates. This way you can add the same value twice, it will only be present once.
This means that you can add a lot List
to Set
yours, you won't have duplicates.
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());
Output:
java.awt.Point[x=0,y=0]
java.awt.Point[x=0,y=1]
java.awt.Point[x=0,y=2]
source to share
It can have several solutions. Since you are using a class java.awt.Point
that already has a method equals
overridden (based on coordinates). This way you can use the contains
class method easily List
.
for(Point point : list2){
if(!list1.contains(point)){
list1.add(point);
}
}
Be sure to use a loop for each
for best performance (don't use an index based loop (this matters if you do LinkedList
)).
ii) Another alternative is to use java.util.Set
and use his method addAll(Set)
. Since Set does not duplicate everything and therefore merges elements effectively.
source to share
How to compare two lists
It's easy, just use equals.
add nonexistent values from arrayList2 to arrayList1
- remove all elements of arrayList1 from arrayList2 and add it to arrayList2. This way only new elements will be added to arrayList2
- get the difference (arrayList1 - arrayList2) and add them to arrayList2 (like CollectionUtils )
Your current solution is probably wrong (it will either skip one item or run forever, depending on your loop):
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
}
Is there a more efficient way
Little tip:
First, make it work (and have good UnitTest coverage). Then (and only then!) If necessary, optimize!
source to share