Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy Two Dimensional ArrayList as new

Tags:

java

arraylist

So the issue I'm having is after copying the 2d arraylist, changing the element from one 2d arraylist affects the other 2d arraylist. I want them to be completely separate in memory.

First example shows how it works correctly with 1d arraylists...

import java.util.ArrayList;
public class QuickTest {

    public static void main(String[] args) {
        ArrayList<Integer> firstList = new ArrayList<>();
        ArrayList<Integer> secondList = new ArrayList<>();

        Integer counter = 2;
        for(int arrI = 0; arrI < 4; arrI++, counter+=2){
            firstList.add(counter);
        }

        secondList = new ArrayList<>(firstList);

        System.out.println("firstList.get(2) = " + firstList.get(2));
        System.out.println("secondList.get(2) = " + secondList.get(2));

        firstList.set(2, 7);

        System.out.println("firstList.get(2) = " + firstList.get(2));
        System.out.println("secondList.get(2) = " + secondList.get(2));
    }
}

Expected output:

enter image description here

Notice how the element from the first arraylist is changed but not the second arraylist element is not changed. This is good and what we want.

Now to try and copy the 2d arraylists...

import java.util.ArrayList;
public class QuickTest {

    public static void main(String[] args) {
        ArrayList<ArrayList<Integer>> firstTwoDimList = new ArrayList<>();
        ArrayList<ArrayList<Integer>> secondTwoDimList = new ArrayList<>();

        firstTwoDimList.add(new ArrayList<Integer>());
        firstTwoDimList.add(new ArrayList<Integer>());
        firstTwoDimList.add(new ArrayList<Integer>());

        Integer counter = 2;
        for(int arrI = 0; arrI < firstTwoDimList.size(); arrI++, counter+=2){
            firstTwoDimList.get(arrI).add(counter);
            counter+=2;
            firstTwoDimList.get(arrI).add(counter);
        }

        secondTwoDimList = new ArrayList<>(firstTwoDimList);

        System.out.println("firstTwoDimList.get(1).get(0) = " + firstTwoDimList.get(1).get(0));
        System.out.println("secondTwoDimList.get(1).get(0) = " + secondTwoDimList.get(1).get(0));

        firstTwoDimList.get(1).set(0, 7);

        System.out.println("firstTwoDimList.get(1).get(0) = " + firstTwoDimList.get(1).get(0));
        System.out.println("secondTwoDimList.get(1).get(0) = " + secondTwoDimList.get(1).get(0));
    }
}

Unexpected output:

enter image description here

Anyone have any idea what the reason for this is, and what the best solution would be?

like image 286
Fiddle Freak Avatar asked Mar 08 '23 08:03

Fiddle Freak


1 Answers

This is what is happening in the 1D array list case, in terms of references:

enter image description here

This is what is happening in the 2D array list case:

enter image description here

This means that when you copy an array list using this:

new ArrayList<>(someOldArrayList)

the items themselves don't get copied, only a new array list object is created, referring to all the items in the old array list.

In the second case, you are only changing what array list 2's items are, but index 1 of first list and second list refers to the same array list 2.

To fix this, you need to copy the array lists inside first list and second list as well. One way to do this:

secondList = new ArrayList<>(firstList.stream().map(x -> new ArrayList<>(x)).collect(Collectors.toList()));
like image 75
Sweeper Avatar answered Mar 16 '23 06:03

Sweeper