initializing ArrayList<>() in methods or constructor

12,460

Solution 1

Because of the fact that each constructor invocation will result in a new distinct object the line this.team = new ArrayList<Player>(); within the constructor will only be called once per instance so thus you'll only ever have one ArrayList instance per object in this specific case.

On the other hand, the addPlayer method can be called as many times as you want on a given object thus this.team = new ArrayList<Player>(); within the addPlayer method will replace (overwrite) the previous list on each method call.

Solution 2

I'm trying to figure out why this.team = new ArrayList() have to be in the constructor?

It doesn't, it has to be initialized before it is used. You can initialize it anywhere you want as long as you don't call printPlayer() or addPlayer() before.

Why can't I have this.team = new ArrayList() initialized in the method?

You actually can. See this example:

public void addPlayer(Player player) {
    if (team == null) {
        team = new ArrayList();
    }

    team.add(player);
}

public void printPlayers() {
    if (team != null) {
        for (Player p : team) {
            System.out.println(p);
        }
    }
}

BUT when it's initialized in the method it only list the last given addition to the list. Is it wrong to have it initialized in the method?

No, it's not wrong. It's typically referred to as "lazy initialization" or "on demand" if you do it in the way of the example above.

Also what's the difference of having it initialized as private ArrayList team = new ArrayList(); before the constructor?

Not much, the difference lies in when it is initialized.

public class Example {
    public static List<T> myList = new ArrayList<T>(); // this is done first
    public static List<T> aList;
    public List<T> someList;
    static {
        // this is also done first (on class load)
        aList = new ArrayList<T>();
    }

    { 
        // this is done right before the constructor (I believe)
        // it is called an 'initialization block'
        someList = new ArrayList<T>();
    }

    public Example() {
        // this one you already know...
    }
}

Solution 3

You can do this in that way (to prevent recreation of ArrayList on every addPlayer method call):

    public void addPlayer(Player player)  {
        if (this.team == null) {
            this.team = new ArrayList<Player>();
        }
        this.team.add(player);
    }

but it will be VERY weird code... Better practice is to initialize 'team' list inside constructor or inline in field declaration. Both of them do the same thing. I prefer to initialize fields inside constructor, but this is only my habit. Other programmers may prefer inline version and this is nothing wrong/bad.

Solution 4

Why can't I have this.team = new ArrayList() initialized in the method?

You're creating a new ArrayList each time and assigning it to this.team. So each time you call addPlayer, you're replacing this.team with a new empty ArrayList and then adding a player with this.team.add(player), so only the last added player is in the ArrayList at all times.

What you could do if you really don't want to create the ArrayList in the constructor is check if this.team is null every time you add a player and if the ArrayList is not created or empty, simply create one.

public void addPlayer(Player player)    {
    if (this.team == null) {
        this.team = new ArrayList<Player>();
    }
    this.team.add(player);
}

Also what's the difference of having it initialized as private ArrayList team = new ArrayList(); before the constructor?

If you're wondering whether the private keyword changes anything, you should read the Java docs on access modifiers: https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

Other than that, initializing before the constructor changes nothing in this case.

Solution 5

Answering just the question:

Also what's the difference of having it initialized as private ArrayList<Player> team = new ArrayList<Player>(); before the constructor?

Nothing, aside from the fact that team would be initialized before name.

Field initializers are syntactic sugar for instance initializers. So this:

private ArrayList<Player> team = new ArrayList<Player>();

is identical to this:

private ArrayList<Player> team;

{
  // This is an instance initializer.
  team = new ArrayList<Player>();
}

and instance initializers are gathered together and inserted into every constructor which invokes (implicitly or explicily) super, in between the call to super and the rest of the constructor body. So this:

public class Team {  

    private ArrayList<Player> team = new ArrayList<>();

    public Team(String name)    {
      this.name = name;
    }
}

is identical to:

public class Team {  

    private ArrayList<Player> team;

    public Team(String name)    {
      super();

      this.team = new ArrayList<>();

      this.name = name;
    }
}
Share:
12,460

Related videos on Youtube

Y Sang
Author by

Y Sang

Updated on June 04, 2022

Comments

  • Y Sang
    Y Sang almost 2 years
    import java.util.ArrayList;
    public class Team {  
    
        private String name;
        private ArrayList<Player> team;
    
        public Team(String name)    {
            this.name = name;
            //how come i have to initialize it here in the constructor to see the full list?          
            this.team = new ArrayList<Player>();
        }
    
        public void addPlayer(Player player)    {
            //why can't i initialize it here in the method, this gives me a list of only recent add?
            //this.team = new ArrayList<Player>(); 
            this.team.add(player);
        }
    
        public void printPlayers()  {            
            for(Player players : this.team) {
                System.out.println(players);
            }
        }
        public String getName() { return this.name; }
    }
    
    • I'm trying to figure out why this.team = new ArrayList<Player>() have to be in the constructor?
    • Why can't I have this.team = new ArrayList<Player>() initialized in the method?
    • I know that when I run it with the code in the constructor it works as intended (it gives me the full list when things are added)
    • BUT when it's initialized in the method it only list the last given addition to the list. Is it wrong to have it initialized in the method?
    • Also what's the difference of having it initialized as private ArrayList<Player> team = new ArrayList<Player>(); before the constructor?
    • takendarkk
      takendarkk about 6 years
      "Why can't I have this.team = new ArrayList<Player>() initialized in the method?" Because you will delete the list and create a new one every time you try to add something. Think about it - every time you call add you say "Hey, create me a new list that has nothing in it and then add this one thing"
    • JDSchenck
      JDSchenck about 6 years
      This is due to scope. When you initialize something in a method, it is born and dies within that method. Once the method ends, so too does that local variable initialized in that method.
    • shmosel
      shmosel about 6 years
      @JDSchenck It has nothing to do with scope.
    • shmosel
      shmosel about 6 years
      I see 5 bullet points but only 2 questions. The answers: 1) It doesn't need to be in the constructor. 2) If you replace the list in the method, it will... replace the list.
    • azro
      azro about 6 years
      Do you think using CAPS LOCK will make us more helpful for you ?
    • Andy Turner
      Andy Turner about 6 years
      Also what's the difference of having it initialized as private ArrayList<Player> team = new ArrayList<Player>(); before the constructor? Nothing.
    • Powerlord
      Powerlord about 6 years
      Style nitpick: As a general rule, you declare a collection as its interface. i.e. private List<Player> team; and then team = new ArrayList<Player>(); where you initialize it. This is because the type of list is an implementation detail.
    • Y Sang
      Y Sang about 6 years
      thanks for the answer, very helpful, sorry about the all caps, hard time formatting questions, I'm new.
  • Y Sang
    Y Sang about 6 years
    Thanks it makes sense, method overwrites got it, didn't think of that
  • Ousmane D.
    Ousmane D. about 6 years
    @YSang if this answer has solved your question then please feel free to accept the answer.