为什么这会返回一个空数组列表?

Why is this returning a null arraylist?

我想创建两个构造函数,一个用 agename 创建一个 Human,另一个用第一个构造函数用 随机年龄姓名

我创建一个名字数组 [Name1, Name2,...,Name9] 并随机选择一个名字,然后我创建一个 1-100 之间的随机年龄并将其存储为 rage,最后我创建一个 Human 及其随机 nameage.

在我的主要方法中,我想创建一个包含 9 个随机人类的数组列表并将其打印出来,但我只得到 9 个姓名:null 和年龄:0 的人类。任何帮助将不胜感激!

class Human {
    int age;
    String name;

    public Human (int myAge, String myName) {
        name = myName;
        age = myAge;
    }

    public Human() {
        ArrayList<String> randomnames = new ArrayList<String>();
        for (int j=1;j<10;j++) {
            randomnames.add("Namn"+j);
        }
        Random randomGenerator = new Random();
        int index = randomGenerator.nextInt(randomnames.size());
        String rname = randomnames.get(index); 

        int rage = (int) (Math.random()*100)

        Human randomPerson = new Human(rage,rname);
    }

    public static void main (String[] args) {

        ArrayList<Object> randomHumans = new ArrayList<Object>();
            for (int j=1;j<10;j++) {
                Human randomPerson = new Human();
                randomHumans.add(randomPerson);
            }
        System.out.println(randomHumans);
    }
}

在你的 Human() 构造函数中,你写了

Human randomPerson = new Human(rage,rname);

这不会初始化您的 Human,而是创建另一个对象。

正确的做法是:

this(rage,rname); // Invoke Human(int, String) constructor

因为 this() 必须在第一行,所以您可以编写如下辅助方法:

private static int randomAge(){
    return (int) (Math.random()*100);
}

private static String randomName(){
    ArrayList<String> randomnames = new ArrayList<String>();
    for (int j=1;j<10;j++) {
        randomnames.add("Namn"+j);
    }
    return randomnames.get((int)(Math.random()*randomnames.size())); 
}

那么你的构造函数将只是

public Human(){
    this(randomAge(),randomName());
}

注意 randomAge()randomName() 必须声明 static 因为你不能在调用 this() 之前调用非静态方法,因为对象没有尚不存在。

ArrayList<String> randomnames = new ArrayList<String>(); 只是 范围 Human(),而不是 main()。您不需要它只从列表中提取一个随机名称。

你的 Human class 不关心 ArrayList。它有两个字段,仅此而已。

In my main method, I want to create an arraylist of 9 random Humans

您需要在 main() 中创建随机人类,而不是从 new Human()

调用

将该代码完全移动到 main(),而不是在那里重复它的尝试。

例如,

public static void main() {

    // Make your list
    List<Human> randomHumans = new ArrayList<>();
    Random randomGenerator = new Random();

    for (int j = 1; j <= 10; j++) {
        // Get the random data
        String randomName = "Namn"+j;
        int rage = (int) (Math.random()*100);

        // add the human
        randomHumans.add(new Human(randomName, rage););
    }

    System.out.println(randomHumans);
}

one that uses the first constructor to create a human with a random age and name

可以简单地写成

public Human() {
    Random randomGenerator = new Random();
    this.name = "Namn"+randomGenerator.nextInt(10);
    this.age = randomGenerator.nextInt(100);
}

您在 Human() 构造函数中所做的一切都不会影响创建的 Human 对象的内部属性。

这是解决您问题的 Human() 构造函数的变体:

public Human() {
    ArrayList<String> randomnames = new ArrayList<String>();

    for (int j=1;j<10;j++) {
        randomnames.add("Namn"+j);
    }

    age = (int) (Math.random()*100);

    Random randomGenerator = new Random();
    int index = randomGenerator.nextInt(randomnames.size());

    name = randomnames.get(index); 
}

正如另一个答案中所述,这是行不通的:

Human randomPerson = new Human(rage,rname);

但使用

this(rage, rname);

也不行,因为它不是构造函数的第一行。

Link: Why do this() and super() have to be the first statement in a constructor?

所以不要调用另一个构造函数,只需这样做:

this.age = rage;
this.name = rname;

一个解决方案是写 this(rage,rname) 但这只有在它是构造函数的第一行时才有效。要使其成为构造函数中的第一行,需要先创建两个函数。

private int randomAge(){
    return randomGenerator.nextInt(100);
}

private String randomName(){
    return "Namn"+randomGenerator.nextInt(10);
}

创建完这两个函数后,第二个构造函数可以说this(randomAge(),randomName()).