Sythe Sythe - 1 month ago 17
Java Question

Adding a row to a pre-existing 2D ArrayList

I've looked around and couldn't quite find an exact article that targets my issue specifically, so if you have a source for information, let me know!

What I'd like to do is add a row to a 2D arraylist that already has some elements in it. For some odd reason I get IndexOutOfBoundsException: Index: 0, Size: 0 as an error when adding.

I think I understand why, it's because the row that I've just added is empty and therefore cannot be accessed. However, even if I add elements (columns) into the row, it still has the same error.

public class Table<T>{
List<List<T>> table;

public Table(Class<T> t) {
table = new ArrayList<List<T>>();
}

public int rows() {
return table.size();
}

public int cols() {
return table.get(0).size();
}

public T get(int i, int j) {
if (i < 0 || i > rows() - 1 || j < 0 || j > cols()-1)
throw new IndexOutOfBoundsException();
return table.get(i).get(j);
}

public T set(int i, int j, T x) {
if (i < 0 || i > rows() - 1 || j < 0 || j > cols()-1)
throw new IndexOutOfBoundsException();
T data = table.get(i).get(j);
table.get(i).set(j, x);
return data;
}

public void addRow(int i) {
if (i < 0 || i > rows()) throw new IndexOutOfBoundsException();
table.add(i, new ArrayList<T>());
}

public void removeRow(int i) {
if (i < 0 || i > rows() - 1) throw new IndexOutOfBoundsException();
table.remove(i);
}

public void addCol(int j) {
if (j < 0 || j > cols()) throw new IndexOutOfBoundsException();
if (rows() == 0) return;
for(int i = 0; i < rows(); i++){
table.get(i).add(j, null);
}
}

public void removeCol(int j) {
if (j < 0 || j > cols() - 1) throw new IndexOutOfBoundsException();
for(int i = 0; i < rows(); i++){
table.get(i).remove(j);
}
}

public static void main(String[] args) {
int nrows = 9, ncols = 6;
Table<Integer> t = new Table<Integer>(Integer.class);
System.out.println("Good");
for (int i = 0; i < nrows; i++) {
t.addRow(t.rows());
}
System.out.println("Done Adding Rows ("+t.rows()+")");
for (int i = 0; i < ncols; i++) {
t.addCol(t.cols());
}
System.out.println("Done Adding Cols ("+t.cols()+")");
for (int i = 1; i <= nrows; i++) {
t.set(i-1, (i-1)%t.cols(), 1111*i);
}
System.out.println("Done Setting");
for (int i = 0; i < t.rows(); i++) {
for (int j = 0; j < t.cols(); j++) {
System.out.print(t.get(i,j)+ " ");
}
System.out.print("\n");
}
t.addCol(2);
System.out.println("Added Col ("+t.cols()+")");
t.addRow(3);
System.out.println("Added Row ("+t.rows()+")");
for (int i = 0; i < t.rows(); i++) {
for (int j = 0; j < t.cols(); j++) {
System.out.print(t.get(i,j)+ " ");
}
System.out.print("\n");
}
}
}


The program output:

Good
Done Adding Rows (9)
Done Adding Cols (6)
Done Setting
1111 null null null null null
null 2222 null null null null
null null 3333 null null null
null null null 4444 null null
null null null null 5555 null
null null null null null 6666
7777 null null null null null
null 8888 null null null null
null null 9999 null null null

Added Col (7)
Added Row (10)
1111 null null null null null null
null 2222 null null null null null
null null null 3333 null null null
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at comp2402a2.Table.get(Table.java:24)
at comp2402a2.Table.main(Table.java:117)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)

Answer

The issue is with your addRow method. In that method, you are adding new ArrayList<T>() for the row you want to insert and later when you access using table.get(3).get(0) it will throw IndexOutofBoundsException because new ArrayList<T>() doesn't actually add any elements. You need to modify the method addRow() to add elements based on cols()

Also cols() need to handle 0 row size, and it needs to be modifed too :

public int cols() {
      if ( table.size() > 0 )
    return table.get(0).size();
      else
          return 0;
  }



public void addRow(int i) {
    if (i < 0 || i > rows()) throw new IndexOutOfBoundsException();

    List<T> list = new ArrayList<T>();
    for ( int j = 0; j < cols(); j++ )
    {
        list.add( null );
    }
    table.add(i, list);
  }
Comments