5

I'm currently learning beginner level Java and have a problem with an ArrayList when used in a constructor as a parameter.

When I have to initialize an ArrayList in the class constructor, I usually write something like this (for the sake of this example, let's assume that I want to create an ArrayList of integers as the class field).

public class Example {

    private ArrayList<Integer> myList;

    public Example(ArrayList<Integer> myInts){
        this.myList = myInts;
    }
       
}

However, when I see people do the same thing in tutorials or textbooks, they write the following code:

public class Example {

    private ArrayList<Integer> myList;

    public Example(int myInts){
        this.myList = new ArrayList<>();
        addIntegers(myInts);
    }
 
    public void addIntegers(int myInts){
        this.myList.add(myInts);
    }
      
}

Is there a difference between the two examples? I assume mine is the wrong way to do it, but actually running both versions gives me the same results (to my limited understanding, that is), so I'm struggling to grasp what sets these two variants apart.

7
  • 2
    In your second example, why do you name a single int parameter myInts (plural)? An int is singular and not a Collection type or array. This is confusing an prevents me understanding your problem. Commented Dec 24, 2020 at 14:48
  • Have you tried passing a null to both examples and then trying to do something with the ArrayList field? With the first one it would throw an exception. Commented Dec 24, 2020 at 14:53
  • @Glains: typo. Treat it as if it where "myInt". Commented Dec 24, 2020 at 14:58
  • I think in the second example the myInts arg to the constructor was also supposed to be an ArrayList<Integer>, not an int, am I right? Commented Dec 24, 2020 at 15:16
  • @KevinAnderson I made a typo: it actually accepts an int called myInt (without the s). Commented Dec 24, 2020 at 15:19

1 Answer 1

2

There is a difference, yes. In the code presented, one would call the constructor like so:

ArrayList<Integer> values = new ArrayList<>(List.of(1, 2, 3, 4));
Example example = new Example(values);

After object construction, the calling side still has access to values, i.e. the internal data structure used by example. By manipulating this data structure, the calling side could bring example in an unexpected state and cause issues.

To prevent such problems, we normally do not directly use reference-types passed in from the outside for internal states, but generate copies of them. This, in essence, is what the second example does. If we still want to pass a List as parameter to the constructor, we can copy the list:

public class Example {

    private ArrayList<Integer> myList;

    public Example(Collection<Integer> myInts) {
        this.myList = new ArrayList<>(Objects.requireNonNull(myInts));
    }

    public Example(Integer... myInts) {
        this(Arrays.asList(Objects.requireNonNull(myInts)));
    }

    public Example(int... myInts) {
        this(Arrays.stream(Objects.requireNonNull(myInts))
                .boxed()
                .collect(Collectors.toList()));
    }           
}

Now if the calling side mutates the List passed to the constructor, the internal datastructure within the Example-instance is not affected since it operates on a copy of the original list.

Remark: If the list-type is mutable, then copying the list is in general not sufficient; we would have to deep-copy the list (i.e. create a copy of each list-entry). This is - in general - not possible in Java.

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

4 Comments

Thanks for your excellent answer: that's exactly what I was looking for.
@ArvindKumarAvinash I did it, but I'm not lv 15.
@CarloBresciani now you are
@ArvindKumarAvinash Thanks. Sorry, but I'm a new user and this is like my second question I ask.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.