0

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?

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
Rafag
  • 719
  • 3
  • 11
  • 27

3 Answers3

2

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.

Community
  • 1
  • 1
Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
2

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.

Brian Roach
  • 76,169
  • 12
  • 136
  • 161
0
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

maxammann
  • 1,018
  • 3
  • 11
  • 17
  • 1
    *so it doesn't need to resize the array every time you add a new entry* the backed array will try to resize every time it lacks the space to add a new entry. – Luiggi Mendoza Jul 28 '13 at 18:48
  • It's not type safe to use arrays of generic types. – Rohit Jain Jul 28 '13 at 18:52
  • @LuiggiMendoza exactly, but I'm not exactly sure how the ArrayList handles the array. Maybe if you remove an element it doesn't resize the array immediately but waits to see if new elements are added. – maxammann Jul 28 '13 at 18:53
  • @RohitJain yeah true, added this – maxammann Jul 28 '13 at 18:54