Reputation:
I'm trying to create a table class, who's rows and columns may expand or shrink, to store ints and strings as a first Java project. The data structure I'm trying to use to represent the table is an ArrayList of ArrayLists, where the initial array's elements all point to a new array list - so the initial array kind of serves as an entrance into rows. This would be a picture of how I have it in my mind, for reference:
The problem I'm having is accessing the inner ArrayLists. I've been reading a bit of documentation, and I can't seem to understand the big issue with why I'm not able to access the inner lists. Some code here:
import java.util.ArrayList;
public class Table {
private int length, width;
private ArrayList newTable;
public Table() {
this.length = this.width = 0;
}
/**
* Testing a few functions
*/
public static void main(String[] args) {
// Just testing a few functions.
Table list1 = new Table();
list1.createTable(4, 4);
list1.displayRow(1);
list1.displayColumn(1);
System.out.println("displayColumn done!");
list1.displayEntireTable();
}
public void createTable(int tableLength, int tableWidth) {
length = tableLength;
width = tableWidth;
this.newTable = new ArrayList();
for (int i = 0; i < tableWidth; i++) {
this.newTable.add(new ArrayList(tableLength));
}
}
public void displayRow(int row) {
System.out.println(this.newTable.get(row));
}
/**
* This function displays the column of the table. Still work which
* needs to be done here.
* @param column
*/
public void displayColumn(int column) {
if (this.newTable.size() >= column) {
for (int i = 0; i < this.newTable.size(); i++) {
// This doesn't work.
System.out.println(this.newTable.get(i).get(column));
}
}
}
public void displayEntireTable() {
for (int i = 0; i < this.newTable.size(); i++) {
System.out.println(this.newTable.get(i));
}
}
}
I'm suspicious that the problem may rely the lack of use in generics, which I'm not quite as familiar with yet as I would like to be. So my question to you, stackoverflow, is whether this data structure - an ArrayList of ArrayLists - is even possible, and if so, where lays my problem?
Upvotes: 2
Views: 9163
Reputation: 12447
Using Java 1.7 generics improvements:
import java.util.ArrayList;
import java.util.List;
public class Table {
private int length, width;
private List<List<String>> newTable;
public Table() {
this.length = this.width = 0;
}
/**
* Testing a few functions
*/
public static void main(String[] args) {
// Just testing a few functions.
Table list1 = new Table();
list1.createTable(4, 4);
list1.displayRow(1);
System.out.println("displayRow done!");
list1.displayColumn(1);
System.out.println("displayColumn done!");
list1.displayEntireTable();
System.out.println("displayEntireTable done!");
}
public void createTable(int tableLength, int tableWidth) {
length = tableLength;
width = tableWidth;
//by java 1.7 diamond feature, some generics can be hidden
this.newTable = new ArrayList<>();
for (int i = 0; i < tableWidth; i++) {
List<String> columns = new ArrayList<>();
for (int j = 0; j < tableLength; j++) {
columns.add(new String("test"));
} //added here
this.newTable.add(columns);
}
}
public void displayRow(int row) {
System.out.println(this.newTable.get(row));
}
/**
* This function displays the column of the table. Still work which
* needs to be done here.
* @param column
*/
public void displayColumn(int column) {
for (int i = 0; i < this.newTable.size(); i++) {
System.out.println("[" + this.newTable.get(i).get(column) + "]");
}
}
public void displayEntireTable() {
for (int i = 0; i < this.newTable.size(); i++) {
System.out.println(this.newTable.get(i));
}
}
}
Upvotes: 2
Reputation:
Change your code that doesn't work to:
System.out.println(((ArrayList) this.newTable.get(i)).get(column));
ArrayList in ArrayList is certainly possibly.
And it is certainly not generics that prohibits you.
Generics is only a compile time check for mistakes and has nothing to do with it. You can complete leave it out, not advised as the probability for class cast exceptions due too mistakes is far larger.
Explanation. The compiler don't knows your ArrayList contains an ArrayList so it doesn't recognize the get method as it trys to invoke it on Object and not ArrayList. So the solution is to cast it if you wan't to use it without generics. However I would recomend to use generics and define your List like this.
private List<List<String> newTable;
Notice how I used List and not ArrayList. Typically your left hand assignment contains an Interface and the right hand an concrete class like ArrayList.
Upvotes: 0
Reputation: 642
First of all, what is your real problem? You don't add any data into the inner ArrayLists, so they are empty.
On the other hand, it is better if you create an object for a row, and store these objects in an arraylist.
Upvotes: 0
Reputation: 726609
I think the problem is that you misunderstood the semantics of the new ArrayList(tableLength)
call: it does not create an array list of tableLength
elements; rather, it creates an ArrayList
with the initial capacity enough to hold at least tableLength
elements.
I am not sure what kind of elements you are planning to add to your ArrayList of ArrayLists, but here is one way to test your code that creates a two-dimensional ArrayList:
for (int i = 0; i < tableWidth; i++) {
ArrayList toAdd = new ArrayList(tableLength);
for (int j = 0; j != tableLength ; j++) {
toAdd.add(new Integer(i*tableLength +j));
}
this.newTable.add(toAdd);
}
Upvotes: 3
Reputation: 198103
Sure it's possible, and I suspect your issues are related to generics, actually -- if you don't use generics, you'll have to do a bunch of casts, which may appear to you as if it just doesn't work.
I'd write this as something like
List<List<Object>> table;
and then I'd add rows by doing table.add(new ArrayList<Object>())
, and access elements with table.get(i).get(j)
.
Upvotes: 2