在方法或构造函数中初始化ArrayList<>()

时间:2018-02-16 22:27:52

标签: java arraylist methods constructor initializing

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; }
}
  • 我试图找出为什么this.team = new ArrayList<Player>()必须在构造函数中?
  • 为什么我不能在方法中初始化this.team = new ArrayList<Player>()
  • 我知道当我使用构造函数中的代码运行它时它按预期工作(它会在添加内容时为我提供完整列表)
  • 但是当它在方法中初始化时,它只列出列表的最后一个添加内容。在方法中初始化它是错误的吗?
  • 在构造函数之前将它初始化为private ArrayList<Player> team = new ArrayList<Player>();的区别是什么?

5 个答案:

答案 0 :(得分:1)

回答这个问题:

  

在构造函数之前将它初始化为private ArrayList<Player> team = new ArrayList<Player>();还有什么区别?

team之前name初始化的事实外,没什么。

字段初始化器是例如初始化器的语法糖。所以这个:

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

与此相同:

private ArrayList<Player> team;

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

和实例初始值设定项一起收集并插入到每个构造函数中,这些构造函数在super的调用和构造函数体的其余部分之间调用(隐式或显式)super。所以这个:

public class Team {  

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

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

与:

相同
public class Team {  

    private ArrayList<Player> team;

    public Team(String name)    {
      super();

      this.team = new ArrayList<>();

      this.name = name;
    }
}

答案 1 :(得分:1)

由于每个构造函数调用都会产生一个新的不同对象,因此构造函数中的行this.team = new ArrayList<Player>();将只为每个实例调用一次,因此您只能拥有一个< / strong>在这种特定情况下每个对象的ArrayList实例。

另一方面,可以根据需要在给定对象上多次调用addPlayer方法,因此 addPlayer 方法中的this.team = new ArrayList<Player>();将替换(覆盖)每个方法调用的上一个列表

答案 2 :(得分:1)

  

我想弄清楚为什么this.team = new ArrayList()必须在构造函数中?

它没有,它必须在使用之前进行初始化。您可以在任何地方初始化它,只要您之前不调用printPlayer()或addPlayer()。

  

为什么我不能在方法中初始化this.team = new ArrayList()?

你真的可以。见这个例子:

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);
        }
    }
}
  

但是当它在方法中初始化时,它只列出列表中最后给定的添加内容。在方法中初始化它是错误的吗?

不,这没错。如果你按照上面的例子的方式进行操作,它通常被称为“延迟初始化”或“按需”。

  

将初始化为私有ArrayList team = new ArrayList()的区别是什么?在构造函数之前?

并不多,不同之处在于初始化时。

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...
    }
}

答案 3 :(得分:1)

您可以这样做(以防止在每次addPlayer方法调用时重新创建ArrayList):

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

但这将是非常奇怪的代码...更好的做法是初始化&#39;团队&#39;在构造函数中列出或在字段声明中内联。他们俩都做同样的事情。我更喜欢在构造函数中初始化字段,但这只是我的习惯。其他程序员可能更喜欢内联版本,这没什么不错/坏。

答案 4 :(得分:1)

  

为什么我不能在方法中初始化this.team = new ArrayList()?

您每次都在创建一个新的ArrayList并将其分配给this.team。因此,每次拨打addPlayer时,您都用新的空ArrayList替换 this.team,然后添加一个this.team.add(player)的播放器,所以只有最后添加的播放器始终在ArrayList中。

如果您真的不想在构造函数中创建ArrayList,那么可以做的是检查每次添加播放器时this.team是否为null并且如果ArrayList不是创建或清空,只需创建一个。

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

将初始化为私有ArrayList team = new ArrayList()的区别是什么?在构造函数之前?

如果您想知道私有关键字是否会发生任何变化,您应该阅读有关访问修饰符的Java文档:https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

除此之外,在这种情况下,在构造函数更改之前进行初始化。