0

My problem is that I want to copy an ArrayList with Objects in it.
Afterwards i want to change the Objects within my "copy List" without changing the Object within the source List.

I already tried:

ArrayList<..> copy = new ArrayList<..>(sourceList); 
Collections.copy(dest, src);

The more specific problem is here:

ArrayList<Exon> regions1 = new ArrayList<>();
regions1.add(r1);
regions1.add(r2);
regions1.add(r3);
System.out.println("Reg 1");
for (Exon e : regions1) {
    System.out.println(e.getStart());
}

ArrayList<Exon> copy = new ArrayList<>(regions1);
System.out.println("Copy");
for (Exon e : copy) {
    e.setStart(2);
    System.out.println(e.getStart());
}
System.out.println("Reg 1 - untouched");
for (Exon e : regions1) {
    System.out.println(e.getStart());
}

The Output I get is:

Reg 1
5
15
100
Copy
2
2
2
Reg 1
2
2
2

The Output I would want is:

Reg 1
5
15
100
Copy
2
2
2
Reg 1
5
15
100
1

2 Answers 2

2

Simply you can create a copy constructor for Exon. then in foreach you must pass new Exon object.(with start=2)

A copy constructor: That's helpful when we want to copy a complex object that has several fields, or when we want to make a deep copy of an existing object.


1- Create copy constructor for Exon

public class Exon {

    private int start;

    //Copy constructor
    public Exon(Exon exon) {
        this.start = exon.getStart();
    }

    //Main Constructor and Getters and Setters

   }

2- Create a copy from main list

 List<Exon> CopyList = mainList.stream().map(exon -> {
        Exon copyExon = new Exon();
        copyExon.setStart(2);
        return new Exon(copyExon);
    }).collect(Collectors.toList());

I wrote your code as follows:

public static void main(String[] args) {

        //Initialize
        ArrayList<Exon> mainList = new ArrayList<>();
        Exon r1 = new Exon();
        r1.setStart(5);
        Exon r2 = new Exon();
        r2.setStart(10);
        Exon r3 = new Exon();
        r3.setStart(15);
        mainList.add(r1);
        mainList.add(r2);
        mainList.add(r3);

        //Print mainList
        System.out.println("Reg 1");
        for (Exon e : mainList) {
            System.out.println(e.getStart());
        }

        //Copy the mainList (I changed your foreach)
        List<Exon> copyList = mainList.stream().map(exon -> {

            //Create New Exon
            Exon copyExon = new Exon(exon);
            copyExon.setStart(2);
            return copyExon ;

        }).collect(Collectors.toList());

        //Print copyList
        System.out.println("Copy");
        for (Exon e : copyList) {
            System.out.println(e.getStart());
        }

        //Print mainList
        System.out.println("Reg 1 - untouched");
        for (Exon e : mainList) {
            System.out.println(e.getStart());
        }
    }

Result :

Reg 1
5
10
15
Copy
2
2
2
Reg 1 - untouched
5
10
15

This link might be useful for Copy Constructor

Sign up to request clarification or add additional context in comments.

1 Comment

The post is edited, (Copy the mainList part).
2

ArrayList in java stores references to objects (not the object itself). When you make a copy, it copies references, and both lists contain refs to the same objects. So you have to make copy of each object yourself. You can do it using streams: copy = regions1.stream().map(e->new Exon(e)).collect(Collectors.toList()).. But you will have to implement copy constructor public Exon(Exon src) {/*copy fields from src to this*/}. And maybe you will have to do the same for nested objects, because they are stored as refs as well.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.