Since the number of columns is a constant, you can just have an List of int[].
import java.util.*;
//...
List<int[]> rowList = new ArrayList<int[]>();
rowList.add(new int[] { 1, 2, 3 });
rowList.add(new int[] { 4, 5, 6 });
rowList.add(new int[] { 7, 8 });
for (int[] row : rowList) {
System.out.println("Row = " + Arrays.toString(row));
} // prints:
// Row = [1, 2, 3]
// Row = [4, 5, 6]
// Row = [7, 8]
System.out.println(rowList.get(1)[1]); // prints "5"
Since it's backed by a List, the number of rows can grow and shrink dynamically. Each row is backed by an int[], which is static, but you said that the number of columns is fixed, so this is not a problem.
Since the number of columns is a constant, you can just have an List of int[].
import java.util.*;
//...
List<int[]> rowList = new ArrayList<int[]>();
rowList.add(new int[] { 1, 2, 3 });
rowList.add(new int[] { 4, 5, 6 });
rowList.add(new int[] { 7, 8 });
for (int[] row : rowList) {
System.out.println("Row = " + Arrays.toString(row));
} // prints:
// Row = [1, 2, 3]
// Row = [4, 5, 6]
// Row = [7, 8]
System.out.println(rowList.get(1)[1]); // prints "5"
Since it's backed by a List, the number of rows can grow and shrink dynamically. Each row is backed by an int[], which is static, but you said that the number of columns is fixed, so this is not a problem.
There are no multi-dimensional arrays in Java, there are, however, arrays of arrays.
Just make an array of however large you want, then for each element make another array however large you want that one to be.
int array[][];
array = new int[10][];
array[0] = new int[9];
array[1] = new int[8];
array[2] = new int[7];
array[3] = new int[6];
array[4] = new int[5];
array[5] = new int[4];
array[6] = new int[3];
array[7] = new int[2];
array[8] = new int[1];
array[9] = new int[0];
Alternatively:
List<Integer>[] array;
array = new List<Integer>[10];
// of you can do "new ArrayList<Integer>(the desired size);" for all of the following
array[0] = new ArrayList<Integer>();
array[1] = new ArrayList<Integer>();
array[2] = new ArrayList<Integer>();
array[3] = new ArrayList<Integer>();
array[4] = new ArrayList<Integer>();
array[5] = new ArrayList<Integer>();
array[6] = new ArrayList<Integer>();
array[7] = new ArrayList<Integer>();
array[8] = new ArrayList<Integer>();
array[9] = new ArrayList<Integer>();
How to create a dynamic 2D Array in java - Stack Overflow
help with multidimensional dynamic array
list - How to create Dynamic Two Dimensional Array [JAVA] - Stack Overflow
How to make dynamic 2d array in Java? - Stack Overflow
Videos
hello, i'm trying to implement a 3-dimensional array where the innermost array needs to be dynamic and hold a specific class type (ill call it foo)
my first thought was to make a 2d array of ArrayList like this
ArrayList<ClassType>[][] 3dArray;
and then in the constructor have
this.3dArray= New ArrayList[noOfRows][noOfColumns]
however whenever i try to to add an object like this
this.3dArray[rowIndex][colIndex].add(nameOfObject)
it gives me a NullPointerException.
Could someone help me fix this or help me find an alternative, solution, ive been stuck for hours. Tthanks
It may be more appropriate to use a Map<Double, List<Double>>. Having the value of the Map as a List<Double> will allow you to expand the list as opposed to an array which has a fixed size.
public static void main(String[] args) throws CloneNotSupportedException {
Map<Double, List<Double>> myMap = create(1, 3);
}
public static Map<Double, List<Double>> create(double row, double column) {
Map<Double, List<Double>> doubleMap = new HashMap<Double, List<Double>>();
for (double x = 0; x < row; x++) {
for (double y = 0; y < column; y++) {
doubleMap.put(x, new ArrayList<Double>());
}
}
return doubleMap;
}
Try to use
Map<String, ArrayList> lastSecArray = new HashMap<>();
ArrayList value = new ArrayList();
value.add(0);
value.add(1);
value.add(2);
lastSecArray.put("0", value);
so you can operate with
lastSecArray.size()
or
lastSecArray.put(...)
or array in array
This isn't all that easy.
You can certainly represent your grid as a List<List<Cell>>.
public Cell getCell(int x, int y) {
return grid.get(x).get(y);
}
However that doesn't give you a free pass to assign to any old number:
List<String> list = new ArrayList<>();
list.set(5,"Hello");
... will throw an IndexOutOfBounds exception too.
You can list.add(string) as many times as you like, and each time the list will grow. But you can't set() beyond its current size.
However if you know you want a cell object for every grid position, and you know that every time it grows it will grow by one, write your algorithm to use add() not set(), and this structure will work well.
Alternatively, as you suggest, a HashMap<Coordinates, Cell> might suit your needs.
You'll need a suitable Coordinates class, with a working hashCode() and equals() implementation. Then you could do:
Map<Coordinates, Cell> grid = new HashMap<>();
grid.put(new Coordinates(80, 100), new Cell());
This would work especially well if you want a "grid" that's sparsely populated but effectively unbounded.
There are plenty more approaches - including implementing your own array-reallocating algorithm (after all, that's what's inside an ArrayList -- find and study its source code, if you're curious).
You should probably also step back and ask why and when you need to change the size of the grid after initialising it. A fixed-size array of fixed-size arrays is a simple solution, and worth sticking with if it works most of the time. If the size only changes occasionally, maybe you'd be better off just creating a new grid and copying the old values into it whenever that happens.
public void setCell(int x, int y, Cell cell) {
if(x >= this.grid.length || y >= this.grid[0].length) {
Cell[][] newGrid = createEmptyGrid(x,y);
copyCells(this.grid,newGrid);
this.grid = newGrid;
}
this.grid[x][y] = cell;
}
createEmptyGrid() here needs to make a decision about the new size -- just big enough to accommodate [x][y]? Or bigger just-in-case? The right thing to do depends on your broader requirements.
You could use ArrayList, but to insert at any index without worrying about going out of bounds, you'd want to use nested Map with a special method for insertion or retrieval.
Map<Integer, Map<Integer, Cell>> grid = new HashMap<Integer, Map<Integer, Cell>>();
for (int x = 0; x <= COLS_NUM; x++) {
Map inner = new HashMap<Integer, Cell>();
for (int y = 0; y < ROWS_NUM; y++) {
inner.put(y, new Cell());
}
grid.put(x, inner);
}
Now you could create a method to set cells int the grid with any indices like this:
public void setCell(Map<Integer, Map<Integer, Cell>> grid, Cell newCell, int x, int y) {
if (grid.containsKey(x)) {
grid.get(x).put(y, newCell);
} else {
grid.put(x, (new HashMap<Integer, Cell>().put(y, newCell)));
}
}
And a method for retrieving a cell:
public Cell getCell(Map<Integer, Map<Integer, Cell>> grid, int x, int y) {
try {
Cell found = grid.get(x).get(y);
return found;
} catch (NullPointerException npe) {
return null;
}
}
To make this useful, you'd want to create a custom class that manages these maps and the insertion / retrieval methods for you, along with other functions useful to your application.
Here's a simpler option using lists. As mentioned above, this won't let you avoid the possibility of getting an IndexOutOfBoundsException.
int ROWS_NUM = (int) canvas.getHeight() / rectangleSize;
int COLS_NUM = (int) canvas.getWidth() / rectangleSize;
List<List<Cell>> array = new ArrayList<List<Cell>>();
for (int x = 0; x < COLS_NUM; x++) {
List inner = new ArrayList<Cell>();
for (int y = 0; y < ROWS_NUM; y++) {
inner.add(new Cell());
}
array.add(inner);
}
You can still access specific cells (the equivalent of array[x][y] in the array this way:
// Find equivalent of arr[2][3]
Cell found = array.get(2).get(3);
However, because you specified that you want to be able to access cells with any index without getting an out of bounds exception, you could choose to implement it with Maps.
Initialize a new Integer[] every time you add a new row.
That is, do it like this:
Integer[] test = new Integer[3];
List<Integer[]> al = new ArrayList<Integer[]>();
int i,t;
test[0]=1;
test[1]=2;
test[2]=3;
al.add(test);
test = new Integer[3]; // Note this line
test[0]=4;
test[1]=5;
test[2]=6;
al.add(test);
test = new Integer[3]; // Note this line
test[0]=7;
test[1]=8;
test[2]=9;
al.add(test);
test = new Integer[3]; // Note this line
test[0]=10;
test[1]=11;
test[2]=12;
al.add(test);
Or better yet, do it this way:
List<Integer[]> al = new ArrayList<Integer[]>();
al.add(new Integer[]{1, 2, 3});
al.add(new Integer[]{4, 5, 6});
al.add(new Integer[]{7, 8, 9});
al.add(new Integer[]{10, 11, 12});
Arrays are objects. ArrayList.add(E) adds a reference to the given E object to the list; it doesn't copy the object itself.
So you should do:
al.add(test);
test = new int[3];
Which creates a new array object, so the second row of data is written into a separate array.
This isn't possible, arrays are always static in length.
Try using a list of lists.
LinkedList<LinkedList<String>> list = new LinkedList<LinkedList<String>>();
list.add(new LinkedList<String>()); // [[]]
list.get(0).add("hello"); // [["hello"]]
list.get(0).add("world"); // [["hello", "world"]]
list.add(new LinkedList<String>()); // [["hello", "world"], []]
list.get(1).add("bonjour"); // [["hello", "world"], ["bonjour"]]
The list can use any class instead of String.
To loop through the lists, you'd need to do something like the following:
for(LinkedList<String> subList : list){
for(String str : subList){
...
}
}
You'll want to use List or ArrayList it allows for 2 dimensional arrays with different data types and you can add/remove rows as needed.
see 2 dimensional array list
Dear those who code in java
is this how you make 2d matrix??
If Yes, c++ is far more simple than java.
List<List<Integer>> dp= new ArrayList<>();
for(int i = 0;i < n;i++){
List<Integer> temp = new ArrayList<Integer>();
for(int j = 0;j < w+1;j++){
temp.add(0);
}
dp.add(temp);
}
or am I missing here something???
I am learning Java just for job switch
generally I do DSA in C++.
How about List<List<Foo>> ?
For Example:
List<List<Foo>> list = new ArrayList<List<Foo>>();
List<Foo> row1 = new ArrayList<Foo>();
row1.add(new Foo());
row1.add(new Foo());
row1.add(new Foo());
list.add(row1);
List<Foo> row2 = new ArrayList<Foo>();
row2.add(new Foo());
row2.add(new Foo());
list.add(row2);
ArrayList<ArrayList<SomeObject>> twodlist = new ArrayList<ArrayList<SomeObject>>();
ArrayList<SomeObject> row = new ArrayList<SomeObject>();
row.add(new SomeObject(/* whatever */));
// etc
twodlist.add(row);
row = new ArrayList<SomeObject>();
// etc
Use collections to do this. For example:
List<List<Integer>> dynamic2D = new ArrayList<List<Integer>>();
dynamic2D.add(new ArrayList<Integer>());
dynamic2D.add(new ArrayList<Integer>());
dynamic2D.add(new ArrayList<Integer>());
dynamic2D.get(0).add(5);
dynamic2D.get(0).add(6);
dynamic2D.get(0).add(7);
System.out.println(dynamic2D.get(0).get(0)); // 5
System.out.println(dynamic2D.get(0).get(1)); // 6
System.out.println(dynamic2D.get(0).get(2)); // 7
Here's one option to consider to keep your 2D array fast for processing. It starts with a fixed size array of int[][] and grows only as necessary:
public class DynamicMatrix2D {
private int[][] matrix = new int[5][5];
public void set(int x, int y, int value) {
if (x >= matrix.length) {
int[][] tmp = matrix;
matrix = new int[x + 1][];
System.arraycopy(tmp, 0, matrix, 0, tmp.length);
for (int i = x; i < x + 1; i++) {
matrix[i] = new int[y];
}
}
if (y >= matrix[x].length) {
int[] tmp = matrix[x];
matrix[x] = new int[y + 1];
System.arraycopy(tmp, 0, matrix[x], 0, tmp.length);
}
matrix[x][y] = value;
}
public int get(int x, int y) {
return x >= matrix.length || y >= matrix[x].length ? 0 : matrix[x][y];
}
public static void main(String[] args) {
DynamicMatrix2D matrix2d = new DynamicMatrix2D();
matrix2d.set(1, 1, 1); // set (1, 1) to 1
matrix2d.set(10, 10, 2); // set (10, 10) to 2
matrix2d.set(100, 100, 3); // set (100, 100) to 3
System.out.println(matrix2d.get(1, 1)); // outputs 1
System.out.println(matrix2d.get(10, 10)); // outputs 2
System.out.println(matrix2d.get(100, 100)); // outputs 3
}
}