Java 为什么我的ArrayList中的对象数组无法保留其值?

Java 为什么我的ArrayList中的对象数组无法保留其值?,java,arrays,arraylist,Java,Arrays,Arraylist,我正在用Java创建一个程序来模拟进化。按照我的设置方式,每一代都由一系列有机体对象组成。每个数组都是ArrayList中的一个元素。每一代,在所有动物死亡之前可能有任何数量的生物,可以有任何数量的有机体对象 出于某种原因,在我的主循环中,当代代相传时,我可以毫无错误地使用此代码,其中allOrgs是当前代的有机体数组,generationNumber是自第一代以来的代数 orgGenerations.add(allOrgs); printOrgs(orgGenerations.get(gene

我正在用Java创建一个程序来模拟进化。按照我的设置方式,每一代都由一系列有机体对象组成。每个数组都是ArrayList中的一个元素。每一代,在所有动物死亡之前可能有任何数量的生物,可以有任何数量的有机体对象

出于某种原因,在我的主循环中,当代代相传时,我可以毫无错误地使用此代码,其中allOrgs是当前代的有机体数组,generationNumber是自第一代以来的代数

orgGenerations.add(allOrgs);
printOrgs(orgGenerations.get(generationNumber));
printOrgs是一种显示有机体数组的方法,其中速度和强度是有机体字段变量:

public void printOrgs(Organism[] list)
{
    for (int x=0; x<list.length; x++)
    {
        System.out.println ("For organism number: " + x + ", speed is: " + list[x].speed + ", and strength is " + list[x].strength + ".");
    }
}
这以及orgGenerations中的每一个其他数组都会在for循环的打印行上返回空指针异常。为什么有机体对象失去了它们的价值

好的,这是我的主要模拟类的所有代码。我承认,这可能有点乱。重要的部分是启动和模拟器方法。战斗型的不适用于这个问题。我想

import java.awt.FlowLayout;
import java.util.*;

import javax.swing.JFrame;

public class Simulator {

//variables for general keeping track
static Organism[] allOrgs;
static ArrayList<Organism[]> orgGenerations = new ArrayList <Organism[]>();

ArrayList<Integer> battleList = new ArrayList<Integer>();

int deathCount;
boolean done;
boolean runOnce;




//setup
Simulator()
{


    done = false;
    Scanner asker = new Scanner(System.in);
    System.out.println("Input number of organisms for the simulation: ");
    int numOfOrgs = asker.nextInt();
    asker.close();
    Organism[] orgArray = new Organism[numOfOrgs];

    for (int i=0; i<numOfOrgs; i++)
    {
        orgArray[i] = new Organism();
    }

    allOrgs = orgArray;
}

//graphsOrgs
public void graphOrgs() throws InterruptedException
{
    JFrame f = new JFrame("Evolution");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(1000,500);
    f.setVisible(true);

    Drawer bars = new Drawer();

    //System.out.println(orgGenerations.size());


    for (int iterator=0;iterator<(orgGenerations.size()-1); iterator++)
    {
        printOrgs(orgGenerations.get(0));
//The 0 can be any number, no matter what I do it wont work
        //System.out.println("first");
        f.repaint();

        bars.data = orgGenerations.get(iterator);

        f.add(bars);
        //System.out.println("before");
        Thread.sleep(1000);
        //System.out.println("end");

    }

}

//prints all Orgs and their statistics
public void printOrgs(Organism[] list)
{
    System.out.println("Number Of Organisms: " + list.length);
    for (int x=0; x<list.length; x++)
    {
        System.out.println ("For organism number: " + x + ", speed is: " + list[x].speed + ", and strength is " + list[x].strength + ".");
    }
    System.out.println();
}

//general loop for the organisms lives
public void start(int reproductionTime) throws InterruptedException
{

    int generationNumber = 0;

    orgGenerations.add(allOrgs);    
    printOrgs(orgGenerations.get(0));

    generationNumber++;


    while(true)
    {
        deathCount = 0;


        for(int j=0; j<reproductionTime; j++)
        {
            battleList.clear();

            for(int m=0; m<allOrgs.length; m++)
            {

                if (allOrgs[m].alive == true)
                    oneYearBattleCheck(m);  
            }

            battle();

        }

        reproduction();
        if (done == true)
            break;

        orgGenerations.add(allOrgs);
        printOrgs(orgGenerations.get(generationNumber));
        generationNumber++;
    }


    printOrgs(orgGenerations.get(2));
}


//Checks if they have to fight this year
private void oneYearBattleCheck(int m)
{
    Random chaos = new Random();
    int speedMod = chaos.nextInt(((int)Math.ceil(allOrgs[m].speed/5.0))+1);
    int speedSign = chaos.nextInt(2);

    if (speedSign == 0)
        speedSign--;

    speedMod *= speedSign;
    int speed = speedMod + allOrgs[m].speed;

    if (speed <= 0)
        speed=1;

    Random encounter = new Random();
    boolean battle = false;

    int try1 =(encounter.nextInt(speed));
    int try2 =(encounter.nextInt(speed));
    int try3 =(encounter.nextInt(speed));
    int try4 =(encounter.nextInt(speed));

    if (try1 == 0 || try2 == 0 || try3 == 0 || try4 == 0 )
    {
        battle = true;
    }


    if(battle == true)
    {
        battleList.add(m);
    }


}

//Creates the matches and runs the battle
private void battle()
{
    Random rand = new Random();

    if (battleList.size()%2 == 1)
    {

        int luckyDuck = rand.nextInt(battleList.size());
        battleList.remove(luckyDuck);
    }

    for(int k=0; k<(battleList.size()-1);)
    {
        int competitor1 = rand.nextInt(battleList.size());
        battleList.remove(competitor1);
        int competitor2 = rand.nextInt(battleList.size());
        battleList.remove(competitor2);

        //Competitor 1 strength
        int strengthMod = rand.nextInt(((int)Math.ceil(allOrgs[competitor1].strength/5.0))+1);
        int strengthSign = rand.nextInt(2);

        if (strengthSign == 0)
            strengthSign--;

        strengthMod *= strengthSign;
        int comp1Strength = strengthMod + allOrgs[competitor1].strength;


        //Competitor 2 strength
        strengthMod = rand.nextInt(((int)Math.ceil(allOrgs[competitor2].strength/5.0))+1);
        strengthSign = rand.nextInt(2);

        if (strengthSign == 0)
            strengthSign--;

        strengthMod *= strengthSign;
        int comp2Strength = strengthMod + allOrgs[competitor2].strength;


        //Fight!
        if (comp1Strength>comp2Strength)
        {
            allOrgs[competitor1].life ++;
            allOrgs[competitor2].life --;
        }
        else if (comp2Strength>comp1Strength)
        {
            allOrgs[competitor2].life ++;
            allOrgs[competitor1].life --;
        }


        if (allOrgs[competitor1].life == 0)
        {
            allOrgs[competitor1].alive = false;
            deathCount++;
        }
        if (allOrgs[competitor2].life == 0)
        {
            allOrgs[competitor2].alive = false;
            deathCount ++ ;
        }
    }

}

//New organisms
private void reproduction()
{

    //System.out.println("Number of deaths: " + deathCount + "\n");
    if (deathCount>=(allOrgs.length-2))
    {
        done = true;
        return;
    }
    ArrayList<Organism> tempOrgs = new ArrayList<Organism>();
    Random chooser = new Random();
    int count = 0;
    while(true)
    {
        int partner1 = 0;
        int partner2 = 0;
        boolean partnerIsAlive = false;
        boolean unluckyDuck = false;

        //choose partner1
        while (partnerIsAlive == false)
        {
            partner1 = chooser.nextInt(allOrgs.length);
            if (allOrgs[partner1] != null)
            {
                if (allOrgs[partner1].alive == true)
                {
                    partnerIsAlive = true;
                }
            }
        }
        count++;
        //System.out.println("Count 2: " + count);

        partnerIsAlive = false;

        //choose partner2
        while (partnerIsAlive == false)
        {
            if (count+deathCount == (allOrgs.length))
            {
                unluckyDuck=true;
                break;
            }

            partner2 = chooser.nextInt(allOrgs.length);

            if (allOrgs[partner2] != null)
            {
                if (allOrgs[partner2].alive == true)
                {
                    partnerIsAlive = true;
                }
            }
        }

        if (unluckyDuck == false)
            count++;

        //System.out.println("count 2: " + count);

        if (unluckyDuck == false)
        {
            int numOfChildren = (chooser.nextInt(4)+1);
            for (int d=0; d<numOfChildren; d++)
            {
                tempOrgs.add(new Organism(allOrgs[partner1].speed, allOrgs[partner2].speed, allOrgs[partner1].strength, allOrgs[partner2].strength ));
            }

            allOrgs[partner1] = null;
            allOrgs[partner2] = null;
        }


        if (count+deathCount == (allOrgs.length))
        {
            Arrays.fill(allOrgs, null);
            allOrgs = tempOrgs.toArray(new Organism[tempOrgs.size()-1]);
            break;
        }
        //System.out.println(count);

    }
}
}

生物种类:

import java.util.Random;

public class Organism {
static Random traitGenerator = new Random();

int life;
int speed;
int strength;
boolean alive;



Organism()
{
    speed = (traitGenerator.nextInt(49)+1);
    strength = (50-speed);
    life = 5;
    alive = true;
}

Organism(int strength1, int strength2, int speed1, int speed2)
{
    Random gen = new Random();
    int speedMod = gen.nextInt(((int)Math.ceil((speed1+speed2)/10.0))+1);
    int speedSign = gen.nextInt(2);


    if (speedSign == 0)
        speedSign--;
    speedMod *= speedSign;
    //System.out.println(speedMod);

    int strengthMod = gen.nextInt(((int)Math.ceil((strength1+strength2)/10.0))+1);
    int strengthSign = gen.nextInt(2);

    if (strengthSign == 0)
        strengthSign--;
    strengthMod *= strengthSign;
    //System.out.println(strengthMod);

    strength = (((int)((strength1+strength2)/2.0))+ strengthMod);
    speed = (((int)((speed1+speed2)/2.0))+ speedMod);
    alive = true;
    life = 5;
}


}

问题在于graphOrgs类,当我尝试打印以检查它是否在为绘制结果做准备时。这就是它返回错误的时候。当我尝试将打印代码放在Simulator类的其他位置时,同样的情况也会发生,一个空指针错误。即使在建立元素的for循环之后也会发生这种情况。

您的
allOrgs
数组中有设置为空元素的代码

        allOrgs[partner1] = null;
        allOrgs[partner2] = null;
您的
orgGenerations
列表多次包含相同的
allOrgs
实例

因此,当您写入
allOrgs[partner1]=null
时,在
orgGenerations
的所有列表元素中,
partner1
的第个元素将变为null,这就是打印方法失败的原因


你应该创建一个数组的副本(你可以使用<代码>数组,复制< /COD>)每次添加新一代到列表中(也考虑创建代码< <生物体>代码>实例的副本,如果你希望每一代记录过去的代码状态>生物体<代码> s,而不是它们的最终状态).

您确定在
orgGenerations
中没有任何空元素吗?默认情况下,数组的单元格为
null
,这解释了为什么
list[x]
可能抛出
NullPointerException
。您应该包含更多的代码,因为我们不知道
orgGenerations.get(generationNumber)
包含什么。我的意思是,我调用的是我已经定义的相同元素。除非它们在之间的某个地方为null,我认为这不会发生。你的意思是你认为你在调用相同的元素。发布您的代码,这将证明或反驳该断言。您需要发布更多代码,以便我们能够复制,我们不知道数据是如何“添加”的,这使得无法解释意外行为。这很有意义,我知道我在哪里犯了这些错误。谢谢
import java.util.Random;

public class Organism {
static Random traitGenerator = new Random();

int life;
int speed;
int strength;
boolean alive;



Organism()
{
    speed = (traitGenerator.nextInt(49)+1);
    strength = (50-speed);
    life = 5;
    alive = true;
}

Organism(int strength1, int strength2, int speed1, int speed2)
{
    Random gen = new Random();
    int speedMod = gen.nextInt(((int)Math.ceil((speed1+speed2)/10.0))+1);
    int speedSign = gen.nextInt(2);


    if (speedSign == 0)
        speedSign--;
    speedMod *= speedSign;
    //System.out.println(speedMod);

    int strengthMod = gen.nextInt(((int)Math.ceil((strength1+strength2)/10.0))+1);
    int strengthSign = gen.nextInt(2);

    if (strengthSign == 0)
        strengthSign--;
    strengthMod *= strengthSign;
    //System.out.println(strengthMod);

    strength = (((int)((strength1+strength2)/2.0))+ strengthMod);
    speed = (((int)((speed1+speed2)/2.0))+ speedMod);
    alive = true;
    life = 5;
}


}
        allOrgs[partner1] = null;
        allOrgs[partner2] = null;