I have to create a 2d array with unknown size. So I have decided to go with a 2d ArrayList the problem is I\'m not sure how to initialize such an array or store information.
Since you only need to store booleans in that 2D array, I would say the most suitable data structure (as both memory consumption and useful interface) would be a java.util.BitSet
, which is basically a class that models a bit array:
As it's a 2D array, I think the way to go would be a:
List<BitSet> bitArrays = new ArrayList<BitSet>();
In the List, you cannot just say: "here's the 5th element" without inserting the first 4 elements. But in the BitSet
, you can simply set()
whatever bit you need and it will automatically expand to the required size.
The short answer to the followup question is
array.get(i1).put(i2, value);
but both the get and put could fail if the size of the ArrayList is <= the index. So if you want to be able to fill in arbitrary values, you need to write methods to expand as necessary. The call would then be something like
putCell(getRow(array, i1), i2, value)
where getRow() knows how to grow the ArrayList of ArrayList, and putCell() knows how to grow the ArrayList.
Well, if you know you have 3 rows and 5 columns (as shown in your data example) you could initialize it as follows:
int[][] a = new int[3][5];
However, if the number of rows changes you could do something like this:
String dataStr = "0,1,0,1,0:0,1,1,0,1:0,0,0,1,0";
String[] rows = dataStr.split(":");
String[] cols = rows[0].split(",");
Now you can initialize:
int[][] a = new int[rows.length][cols.length];
This will accomodate changing row and col size. Might not be the most elegant approach but it should work.
If you don't have all of the data in advance to be able to leverage aioobe's solution, you could use a Table from Google's Guava library.
Table<Integer,Integer,Integer> matrix = new HashBasedTable<Integer,Integer,Integer>();
matrix.put(rowIndex,columnIndex,value);
The primary drawback of this is that it's not incredibly fast or memory efficient if you are working with a large quantity of data, as everything is a hash lookup and primitives are wrapped by Integer.
import java.util.*;
public class ArrayListDS {
public static void main( String [] args ) {
ArrayList<ArrayList<Integer>> row = new ArrayList<ArrayList<Integer>>();
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number of row: ");
int n = sc.nextInt();
for(int i = 0; i < n; i++){
ArrayList<Integer> col = new ArrayList<Integer>();
row.add(col);
System.out.println("Enter the number of column: ");
int m = sc.nextInt();
for(int j = 0; j < m; j++){
col.add(sc.nextInt());
}
System.out.println();
}
System.out.println(row);
}
}
List<List<Integer>> array = new ArrayList<List<Integer>>();
// add row:
array.add( new ArrayList<Integer>() );
// add a column:
array.get( array.size() -1 ).add( 1 );
Working demo:
import java.util.*;
import static java.lang.System.out;
class Load {
public static void main( String ... args ) {
List<List<Integer>> array = new ArrayList<List<Integer>>();
Scanner input = new Scanner(System.in);
out.println("Enter n:");
int n = input.nextInt();
out.println("Enter m:");
int m = input.nextInt();
out.println("Enter the values:");
for( int i = 0 ; i < n ; i++ ) {
// add row:
List<Integer> list = new ArrayList<Integer>();
array.add( list );
for( int j = 0 ; j < m ; j++ ) {
// add a column:
// array.get( array.size() -1 ).add( 1 ); or
list.add( input.nextInt() );
}
}
out.println("Result:");
out.println( array );
}
}
Output:
C:\>java Load
Enter n:
3
Enter m:
6
Enter the values
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Result:
[[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11], [12, 13, 14, 15, 16, 17]]