Michelle
Michelle

Reputation: 852

error : java.lang.ArrayIndexOutOfBoundsException on Android

I have this code : indexOfChromosomes : 48 indexOfGens : 20 double Truncation; double Crossover; double Mutation; int Generation;

private Context context;

int indexOfChromosomes;
int indexOfGens;
int gensNumber;
int chromosomesNumber;

public AdapterDB(int Bits, double Truncation, double Crossover, double Mutation, int Chromosomes, int Generation, Context ctx)
{
    this.indexOfGens = Bits;
    this.Truncation = Truncation;
    this.Crossover = Crossover;
    this.Mutation = Mutation;
    this.indexOfChromosomes = Chromosomes;
    this.Generation = Generation;
    this.context = ctx;
    DBHelper = new DatabaseHelper (context);
}

String [][] population = new String[indexOfChromosomes][indexOfGens];

    public void generateChromosome()
{       
    for(chromosomesNumber = 0; chromosomesNumber < indexOfChromosomes ; chromosomesNumber++)
    {
                    int o = 0;
        for(gensNumber = 0; gensNumber < 12 ; gensNumber++)
        {
            Cursor l = db.rawQuery("SELECT _id, key_foodstuff, key_calorie, key_carbohydrate, key_fat, key_protein FROM (food INNER JOIN categories ON food.key_nocategory = categories.nocategories) WHERE key_type='primary' AND _id!=164 AND (key_carbohydrate!=0 OR key_protein!=0 OR key_fat!=0) ORDER BY RANDOM() LIMIT 1", null);

            if((l.moveToFirst()) && (l!=null))
            {   
                if (o == indexOfGens)
                {
                    gensNumber = 0;
                    sumOfCarbohydrateMor = 0;
                    sumOfFatMor = 0;
                    sumOfProteinMor = 0;
                    sumOfCalorieMor = 0;
                    o = 0;
                }

                population[chromosomesNumber][gensNumber] = l.getString(0);
                morning_food[k] = l.getString(3);
                sumOfCarbohydrateMor = sumOfCarbohydrateMor + Double.parseDouble(morning_food[k]);  
                morning_food[f] = l.getString(4);
                sumOfFatMor = sumOfFatMor + Double.parseDouble(morning_food[f]);
                morning_food[p] = l.getString(5);   
                sumOfProteinMor = sumOfProteinMor + Double.parseDouble(morning_food[p]);
                morning_food[c] = l.getString(2);   
                sumOfCalorieMor = sumOfCalorieMor + Double.parseDouble(morning_food[c]);
                if (((sumOfCarbohydrateMor >= (morning_car-(morning_car*0.2))) && (sumOfCarbohydrateMor <= morning_cal*1.1)) && ((sumOfProteinMor >= (morning_pro-(morning_pro*0.2))) && (sumOfProteinMor <= morning_pro*1.1)) && ((sumOfFatMor >= (morning_fat-(morning_fat*0.2))) && (sumOfFatMor <= morning_fat*1.1)))
                //if((sumOfCarbohydrateMor > (morning_car*0.6)) && (sumOfProteinMor > (morning_pro*0.7)) && (sumOfFatMor > (morning_fat*0.8)))
                {
                    Log.e("lala", "lalala");
                    break;
                }

                if ((sumOfCarbohydrateMor > (morning_car*1.1)) || (sumOfProteinMor > (morning_pro*1.1)) || (sumOfFatMor > (morning_fat*1.1)) || (sumOfCalorieMor > (morning_cal*1.1))
                {

                    morning_food[k] = l.getString(3);
                    sumOfCarbohydrateMor = sumOfCarbohydrateMor - Double.parseDouble(morning_food[k]);
                    morning_food[f] = l.getString(4);
                    sumOfFatMor = sumOfFatMor - Double.parseDouble(morning_food[f]);
                    morning_food[p] = l.getString(5);
                    sumOfProteinMor = sumOfProteinMor - Double.parseDouble(morning_food[p]);
                    morning_food[c] = l.getString(2);
                    sumOfCalorieMor = sumOfCalorieMor - Double.parseDouble(morning_food[c]);
                    gensNumber--;
                    o++;

                }   

            }
        }

and it error in line : 48

The error says that : java.lang.ArrayIndexOutOfBoundsException

any idea? Thx u

Upvotes: 1

Views: 695

Answers (3)

Jon Skeet
Jon Skeet

Reputation: 1500525

This is your problem:

String [][] population = new String[indexOfChromosomes][indexOfGens];

This occurs outside your constructor, and is therefore executed before your constructor, when indexOfChromosomes and indexOfGens are both still 0. Put the initialization inside your constructor. Here's a simpler example showing the same problem:

public class Test {
    private int size;

    public Test(int size) {
        this.size = size;
    }

    private String[] array = new String[size];

    public static void main(String[] args) {
        Test t = new Test(5);
        System.out.println(t.array.length);
    }
}

And the fixed version:

public class Test {
    private int size;
    private String[] array;

    public Test(int size) {
        this.size = size;
        array = new String[size];
    }


    public static void main(String[] args) {
        Test t = new Test(5);
        System.out.println(t.array.length);
    }
}

Note that the positioning of the variable declaration with respect to the constructor makes no difference to the execution flow.

EDIT: As for why it's now looping forever - in the middle of your code you have:

if (o == indexOfGens)
{
    gensNumber = 0;
    ...
}

which will reset the inner loop back to (nearly) the start (not quite the start, as gensNumber will be incremented at the end of the loop body, before the start of the next iteration).

It's not at all clear what you're trying to do, but I suspect that's not helping.

I'd also encourage you to use local variables wherever possible - it's very unusual to use an instance variable as a loop counter, for example.

Finally, I'd encourage you to break up your large method into smaller ones for readability.

Upvotes: 1

SuperTron
SuperTron

Reputation: 4233

It's because you define the population string outside a function, without initializing the indexOfChromosomes to 48 and the indexOfGens to 20. Try defining the population at the top and setting it to something new in the adapter, AFTER you've set your variables. Something like this:

double Truncation;
double Crossover;
double Mutation;
int Generation;

private Context context;

int indexOfChromosomes;
int indexOfGens;
int gensNumber;
int chromosomesNumber;

String [][] population;

public AdapterDB(int Bits, double Truncation, double Crossover, double Mutation, int Chromosomes, int Generation, Context ctx)
{
    this.indexOfGens = Bits;
    this.Truncation = Truncation;
    this.Crossover = Crossover;
    this.Mutation = Mutation;
    this.indexOfChromosomes = Chromosomes;
    this.Generation = Generation;
    this.context = ctx;
    DBHelper = new DatabaseHelper (context);

    //Create population after initializing variables.
    population = new String[indexOfChromosomes][indexOfGens];
}   

Upvotes: 1

marimaf
marimaf

Reputation: 5410

Try setting

population = new String[indexOfChromosomes][indexOfGens];

inside your adapterDB.

It looks like when you are initializing populatioin, indexOfChromosomes and indexOfGens are not initialized yet, so you are creating an array of size 0. So when you call

population[chromosomesNumber][gensNumber] 

you get java.lang.ArrayIndexOutOfBoundsException

Upvotes: 1

Related Questions