So I thought that it might be a good idea to try to make what is stated in the title. It has an initial size of 1x1 and can expand as much as you like. I figured it to be more convenient that having “String[][] matrix = new String[1][1];” and having to provide dimensions from the get go. Anyway, the code is obviously not perfect, feel free to use it and tell me if I’ve done anything wrong or hideously impractical.
public class ExpandableMatrix<T> {
private T[][] data;
private boolean locked = false;
@SuppressWarnings("unchecked")
public ExpandableMatrix(){
data = (T[][]) new Object[1][1];
}
public T get(int x,int y){
try{
return data[x][y];
}catch(Exception e){
return null;
}
}
public void fill(T object){
for(int x = 0; x < getWidth();x++){
for(int y = 0; y < getHeight();y++){
put(object, x,y);
}
}
}
public ExpandableMatrix<T> expand(int newWidth, int newHeight) {
if(locked){
new Exception("Matrix cannot be expanded, it is locked.").printStackTrace();
return this;
}
T[][] newData = newMatrix(newWidth, newHeight);
if(newWidth < getWidth() || getHeight() > newHeight){
try{
this.data = getSection(0,0,newWidth, newHeight);
}catch(Exception e){
for(int x = 0; x < newWidth; x++){
for(int y = 0; y < newHeight;y++){
newData[x][y] = get(x,y);
}
}
this.data = newData;
}
return this;
}
for(int x = 0; x < data.length;x++){
System.arraycopy(data[x],0, newData[x], 0, data[x].length);
}
this.data = newData;
return this;
}
public void put(T object, int x, int y){
if(x < 0 || y < 0)
throw new IllegalArgumentException("X and Y must be positive");
if(x > data.length || y > data[0].length){
expand(x,y);
}
data[x][y] = object;
}
@SuppressWarnings("unchecked")
private T[][] newMatrix(int width, int height){
return (T[][]) new Object[width][height];
}
public T[][] getSection(int x, int y, int width, int height){
if(isValidPosition(x,y) || isValidPosition(x + width, y + height))
throw new IllegalArgumentException("Unable to get section, section invalid");
T[][] newData = newMatrix(width, height);
for(int x1 = x;x1 < x + width; x1++){
for(int y1 = y; y1 < y + height;y1++){
newData[x1 - x][y1 - y] = get(x1,y1);
}
}
return newData;
}
public boolean isValidPosition(int x, int y){
return (x < 0 || x > data.length || y < 0 || y > data[0].length);
}
public void clear(){
data = newMatrix(1,1);
}
public void lock(){
locked = true;
}
public void remove(int x, int y){
data[x][y] = null;
}
public T[][] asMatrix(){
return data;
}
public int getWidth(){
return data.length;
}
public int getHeight(){
return data[0].length;
}
}