Rafag
Rafag

Reputation: 729

ArrayOutOfBoundsException when accessing ArrayList inside ArrayList

I have the following problem using an ArrayList of ArrayList. I do the next:

Hashtable<SensorType, ArrayList<Float>> hash = new Hashtable<SensorType, ArrayList<Float>>();

int numKeys = sensors.size();
ArrayList<ArrayList<Float>> arrays = new ArrayList<ArrayList<Float>>(numKeys);  

for(int i = 0; i < arrays.size(); i++){
    ArrayList<Float> aux = new ArrayList<Float>();
    arrays.add(aux);
}

String columns = getColumnsName(sensors);

String sql = "select " + columns + " from " + nameTable + " where " + ID + " BETWEEN " +
    start + " AND " + end + ";"; 

Cursor c = db.rawQuery(sql, null);      
c.moveToFirst();

while(!c.isAfterLast()){

    for(int i = 0; i < numKeys; i++)
        arrays.get(i).add(c.getFloat(i));

    c.moveToNext();
}

This always gives me an ArrayOutOfBoundsException. It tells that the size of every array (inner) is 0. What am I doing wrong?

Upvotes: 0

Views: 82

Answers (3)

Rohit Jain
Rohit Jain

Reputation: 213351

This loop:

for(int i = 0; i < arrays.size(); i++){
    ArrayList<Float> aux = new ArrayList<Float>();
    arrays.add(aux);
}

will not even execute once. Since arrays.size() is 0. So, your arrays is empty only. And hence you get that exception.

I guess you need to change your loop to:

for(int i = 0; i < numKeys; i++)

Apart from that, I would do some changes in your code:

  • I would declare my list as:

    List<List<Float>> arrays = new ArrayList<List<Float>(numKeys);
    

    Also, be sure you know why you are passing that parameter to ArrayList constructor. That is used for setting initial capacity of ArrayList. It doesn't fix it's size as in case of arrays. You can skip that parameter, if your ArrayList is not going to be very large.

  • I would use HashMap instead of Hashtable with Map as reference type. See this post for reasons.

Upvotes: 2

maxammann
maxammann

Reputation: 1048

int numKeys = sensors.size();
ArrayList<ArrayList<Float>> arrays = new ArrayList<ArrayList<Float>>(numKeys);  

for(int i = 0; i < arrays.size()/*<- This returns 0*/; i++){
    ArrayList<Float> aux = new ArrayList<Float>();
    arrays.add(aux);
}

Why arrays.size() returns 0?

Because if you pass numKeys to the constructor of the ArrayList it just adjusts the backed array, so it doesn't need to resize the array every time you add a new entry. arrays.size() returns 0 because you never added a new entry, so replace arrays.size() with numKeys. The initial size has nothing to do with the actual size of the list.

Javadoc: http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html#ArrayList(int)

EDIT: (Not type safe)

You also could replace the arrays ArrayList with a simple array:

ArrayList<Float>[] arrays = new ArrayList<Float>[numKeys];  

Max

Upvotes: 0

Brian Roach
Brian Roach

Reputation: 76908

When you call arrays.size() you will get back 0. That method returns the number of objects in the List. Therefore, your loop never inserts anything.

When you call the ArrayList constructor you're using, the int is the initial capacity for the list - this is an optimization for when you know in advance how large your ArrayList is going to be to prevent unnecessary resizing later when adding items.

Upvotes: 2

Related Questions