0

I have a main method which creates a List<Long>. I then have another class whose state is a List<Long> - the goal of this class is to take in the main method's List<Long> as its state and do manipulations to it without affecting the main method's List<Long>.

However the problem that I am facing is that this other class is impact both its state (its private List<Long>) as well as the List<Long> in the main method.

How do I adjust my code such that setTesting(...) is only able to influence the state of its class?

public class Main {
    public static void main(String[] args) { 

        final List<Long> mainlist = new ArrayList<Long>();
        mainlist.add((long) 1);
        mainlist.add((long) 2);
        mainlist.add((long) 3);


        Test testlist = new Test();
        testlist.setTesting(mainlist);

        System.out.println(testlist.getTesting());
        testlist.removal((long) 1);
        System.out.println(testlist.getTesting());



    }
}





public class Test {

    private List<Long> testing = new ArrayList<Long>();

    public Test() {
    }

    public void removal(Long remove) {
        this.testing.removeAll(Collections.singleton(remove));
    }

    public void setTesting(List<Long> list) {
        this.testing = list;
    }

    public List<Long> getTesting() {
        return this.testing;
    }



}
user2763361
  • 3,789
  • 11
  • 45
  • 81

3 Answers3

1

As the testing reference in your class is referring to the same list you created in main method, so making any change will change the main method list. If you want to create a new list using the list passed in your setTesting method, then do something like this:

   public void setTesting(List<Long> list) {
        this.testing = new ArrayList<Long>(list);
    }

using the new keyword in setTesting, a new list will be created using the input list. Any change to this new list will not impact the original main method list.

Also you can remove the initialization of testing list from the class level, simply declare it:

private List<Long> testing;
Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136
1

Make a defensive copy.

public void setTesting(List<Long> list) {
     this.testing = new ArrayList<Long>(list);
    }

The current problem is that your Test object and main method both refer to the same list. So, if anyone modifies the list other sees it to. The solution is just to have different copy for both of them.

A word of caution: the solution above will copy the same references in the new list too, though here it doesn't matter.

rocketboy
  • 9,573
  • 2
  • 34
  • 36
  • About your word of caution: But that doesn't matter in this case because class `Long` is immutable. – Jesper Sep 14 '13 at 06:26
1

That happens because there is only one List<Long>. In the main method you're passing it to setTesting in class Test, but there you're just storing a reference to the list that was created in main. Remember that in Java, variables are references to objects - they are not the objects themselves. If you use =, like you do in your setTesting method, you are only copying the reference to the list, you're not creating a copy of the list. If you want the Test object to have its own copy, you'll have to copy the list yourself:

public void setTesting(List<Long> list) {
    // Creates a copy of the list
    this.testing = new ArrayList<Long>(list);
}
Jesper
  • 202,709
  • 46
  • 318
  • 350