Search code examples
javaarraylistschedulinground-robin

Why does mutating an object in one ArrayList change it in all other ArrayLists?


I am making a cpu scheduling simulator (for a school project). I have a problem with my roundRobin function. When I do c.get(i).jobTime -= 2; and c.get(i).jobTime -= 1; it effects my other ArrayLists, so I can't do my other functions. Before I call roundRobin2 my lists are completely normal. Why does this happen?

For example this is how my list4 looks like after roundRobin2

list 4: [Job101 0, Job102 0, Job103 0, Job104 0, Job105 0, Job106 0]

This is how I read in the file, and put the Jobs objects into my ArrayLists.

Scanner input = new Scanner(new File("testdata1.txt"));
ArrayList<Jobs> list = new ArrayList<Jobs>();
ArrayList<Jobs> list2 = new ArrayList<Jobs>();
ArrayList<Jobs> list3 = new ArrayList<Jobs>();
ArrayList<Jobs> list4 = new ArrayList<Jobs>();

Jobs first;

while (input.hasNext()) {
    first = new Jobs(input.next(), input.nextInt());
    list.add(first);
    list2.add(first);
    list3.add(first);
    list4.add(first);
}

input.close();

This is my roundRobin2

public void roundRobin2(ArrayList<Jobs> c, int sT) {
    int size = c.size();
    int cT = 0;
    int ccT = 0;
    while (!c.isEmpty()) {
        int i = 0;
        System.out.println(c);
        for (i = 0; i < size; i++) {
            if ((c.get(i).jobTime) >= 2) {
                c.get(i).jobTime -= 2;
                cT += 2;

                if ((c.get(i).jobTime) == 0) {
                    ccT += cT;
                }
            } else {
                (c.get(i).jobTime) -= 1;
                cT += 1;

                if ((c.get(i).jobTime) == 0) {
                    ccT += cT;
                }
            }
        }
        for (i = 0; i < size; i++) {
            if ((c.get(i).jobTime) == 0) {
                c.remove(i);
                size = c.size();
            }
        }
    }
    System.out.println("\nAverage completion times: "+ccT+"/"+sT+" = "+((ccT)/sT));
}

Solution

  • In each iteration you are creating only a single object and adding it to all 4 lists. When you mutate that object you, well, mutate it. That mutation will be reflected in all the lists because they all store the same object reference.

    while (input.hasNext()) {
        first = new Jobs(input.next(), input.nextInt());
        list.add(first);
        list2.add(first);
        list3.add(first);
        list4.add(first);
    }
    

    Instead you need to add a new object reference to each list (if you want a clone of the object to be stored in each list).

    while (input.hasNext()) {
        String s = input.next();
        int i = input.nextInt();
        list.add(new Jobs(s, i));
        list2.add(new Jobs(s, i));
        list3.add(new Jobs(s, i));
        list4.add(new Jobs(s, i));
    }
    

    In the first code sample list.get(n) == list2.get(n) will be true (true for any valid n and for any two lists from your 4). In the second sample it will be false as you now have completely unrelated objects that just happen to store the same values at the point they are added to the list.