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 ....

+3


source to share


7 replies


  • 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:

    Don't Be Smart: Twisted Double Click Template

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]

+4


source


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.

+2


source


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]

      

+1


source


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.

+1


source


You can do something like this

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

      

0


source


You have to override your equal function in the point class

and then you can iterate over those two lists and compare their values.

0


source


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!

0


source







All Articles