【问题标题】:How to make an ArrayList inside a class and why like that?如何在一个类中创建一个 ArrayList,为什么这样?
【发布时间】:2020-11-24 12:07:46
【问题描述】:

我创建了一个简单的游戏,其中有一个 User 类用于存储用户数据。我想将一种特定类型的数据存储在ArrayList 中,并且我想在游戏期间向其中添加内容。下面你可以看到我认为我必须写它,但显然它是不正确的。为什么不?我该如何正确地做到这一点,为什么会这样?我在互联网上搜索过,但没有找到。

public Class User {
    List positions;
}
User x = new User;
x.positions = new ArrayList;

x.positions.add(1);
x.positions.add(2);

【问题讨论】:

  • 您没有正确调用构造函数,即new ArrayList。您缺少括号。
  • 两件事:A)请阅读minimal reproducible example ...在以后的问题中,包括有关您看到的错误的信息...但更重要的是:B)不要指望这里的人简单地解释java语法给你。您放入代码中的每个字符都很重要。因此,当您阅读教程时,一本书会注意所有细节。例如,不是您的代码完全遗漏了列表的“泛型”部分,通常您会执行 List<Coordinate> positions = new ArrayList<>(); 之类的操作。
  • 在类声明中,关键字“class”必须用小写 c 书写,如public class User {...}

标签: java list class arraylist methods


【解决方案1】:

我会将List 更改为ArrayList<T>,其中T 是一种对象,因此它对可以存储的内容有限制。此外,在您的班级中,您希望对其进行设置,以便拥有私有变量,并使用 setter 和 getter 来访问这些变量。

我还包括了一个构造 ArrayList 的初始化程序块,并且在每次创建新用户对象时都会调用此初始化程序块,即使您在类中有多个构造函数也是如此。如果不构造 ArrayList,它将为 null。

public class User {
    private ArrayList<T> positions;

    public ArrayList<T> getPositions() {
        return this.positions;
    }

    public void setPosition(ArrayList<T> position) {
        this.position = position;
    }

    // Initializer block
    {
        this.position = new ArrayList<>();
    }
}

有了这个,你就可以调用x.getPosition.add()来添加职位、查看职位、删除职位等。

【讨论】:

    【解决方案2】:

    首先,您应该将职位设为私有。 其次,您需要为职位制定适当的公共 getter 和 setter 方法。

    请看下面的一些示例: 类用户(包省略):

    import java.util.ArrayList;
    import java.util.List;
    
    public class User {
        private List<Integer> positions = new ArrayList<>();
    
        public List<Integer> getPositions() {
            return positions;
        }
    
        public void setPositions(List<Integer> positions) {
            this.positions = positions;
        }
    }
    

    主类(包省略):

    import java.util.ArrayList;
    import java.util.List;
    
    public class MainApp {
        public static void main(String[] args) {
            User user = new User();
            user.getPositions().add(1);
            user.getPositions().add(2);
    
            // another way
            List<Integer> positions = user.getPositions();
            positions.add(3);
    
            // another way
            List<Integer> myNewList = new ArrayList<>();
            myNewList.add(4);
            myNewList.add(5);
            myNewList.add(6);
            // below will replace list 123 with 456
            user.setPositions(myNewList);
        }
    }
    

    【讨论】:

    • 注意:您的答案比 Vicas 的答案要好,但仍然:将列表返回给客户端代码有什么意义?一个好的界面的想法是隐藏信息。第二个您拥有该列表的吸气剂,并允许客户直接更新该列表,您就会打开一堆问题。为列表设置 getter/setter 是错误的方法。
    • 你说的是真的。在 getPositions() 中,它应该返回 (1) 列表的副本,以便在操作副本时原始列表不会受到影响。 (2) 一个不可修改的列表,使得调用者不能对列表进行任何更改
    • 为什么要公开列表?一个好的接口的重点是提供所需的功能,而不是数据结构。不要创建让您的客户端代码可以使用的接口 - 以某种方式编写接口,以便它满足客户的需求。不知何故与“告诉不问”干净代码原则有关。
    【解决方案3】:

    几件事:

    1. 使用正确的构造函数实例化您的ArrayList目前,您的代码不会编译,因为您没有调用构造函数。它应该是new ArrayList&lt;T&gt;(););

    2. 为您的List 定义更具体的粒度,并使用通用类型参数声明它,例如List&lt;TypeYouWantToStore&gt;。否则,您的列表是 原始类型,并且不会对您存储的内容有任何限制;

    3. 为您的List 字段定义访问器(getter)和mutators(设置器),而不是直接作为public 字段访问它。然后您将拥有:

      x.getPositions().add(1);
      
    4. 我会从 User 类的构造函数初始化您的 List 字段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-17
      • 2020-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多