出于测试目的,我目前遇到了一种情况,我不得不随机创建一个二维数组,每行有不同长度的列。例如,请考虑以下插图:
0.0 0.1 length = 2
1.0 1.1 1.2 length = 3
2.0 length = 1
我知道如何以非随机的方式创建这样的数组:
new Float[][] {
{ 0.0, 0.1 },
{ 1.0, 1.1, 1.2 },
{ 2.0 }
};
如果方法anyFloat()
返回随机生成的Float
值,则随机生成矩阵的每个值也很容易:
new Float[][] {
{ anyFloat(), anyFloat() },
{ anyFloat(), anyFloat(), anyFloat() },
{ anyFloat() }
};
但挑战是为数组做这样的事情(我想这是不可能的,因为我们必须知道创建数组时所需的内存量):
List<List<Float>> matrix = new ArrayList<List<Float>>();
int rows = anyRows();
for (int row = 0; row < rows; row++) {
matrix.add(anyListOfFloats());
}
现在我的问题是:我们可以为数组实现此目的还是将matrix
转换为数组?
答案 0 :(得分:3)
是的,可以做到。
诀窍是知道n维数组只需要立即初始化其第一维的大小。例如:
float[][] matrix = new float[randSz()][];
然后,您可以使用指针将n维数组的第一维填充到for循环中的其他数组:
for (int i = 0; i < matrix.length; ++i) {
matrix[i] = new float[randSz()];
}
这就是为什么这是可能的。 Java中的n维数组存储为指向其他数组的指针数组。所以在记忆中你会有这样的东西:
2d_array:
[ arr_pointer_1 ][ arr_pointer_2 ][ arr_pointer_3 ]
arr_pointer_1:
[ 0.0 ][ 0.1 ]
arr_pointer_2:
[ 1.0 ][ 1.1 ][ 1.2 ]
arr_pointer_3:
[ 2.0 ]
请记住,第一维中的指针不需要立即初始化 - 它们可以作为空指针开始。
matrix_array:
[ null ][ null ][ null ]
以下是与您提出问题的格式相匹配的完整示例:
private static final Random RAND = new Random(new Date().getTime());
private static final int ROW_UPPER_BOUND = 10;
private static final int COL_UPPER_BOUND = 8;
/**
* @param args
*/
public static void main(String[] args) {
float[][] matrix;
int rows = anyRows();
// Create array of null "pointers".
matrix = new float[rows][];
for (int row = 0; row < rows; ++row) {
// Assign array "pointers" to first dimension of matrix.
matrix[row] = anyArrayOfFloats();
}
System.out.println(matrixToString(matrix));
}
public static int anyRows() {
return RAND.nextInt(ROW_UPPER_BOUND) + 1;
}
public static float anyFloat() {
return RAND.nextFloat();
}
public static float[] anyArrayOfFloats() {
int sz = RAND.nextInt(COL_UPPER_BOUND) + 1;
float[] arr = new float[sz];
for (int i = 0; i < sz; ++i) arr[i] = anyFloat();
return arr;
}
public static String matrixToString(float[][] matrix) {
StringBuilder builder = new StringBuilder();
builder.append("[");
boolean first = true;
for (float[] fArr: matrix) {
if (first) {first = false;} else {builder.append(", ");}
builder.append(Arrays.toString(fArr));
}
builder.append("]");
return builder.toString();
}
答案 1 :(得分:1)
由于你指出的原因,数组不可能。但是,确实可以将矩阵列表转换为数组。
为此,您可以使用List.toArray(T[])。您必须在表示行的列表上使用它,并在行列表上使用它(这是您的矩阵)。
我没有对此进行过测试,但它应该可以解决这个问题:
public MyType[][] matrixToArray(List<List<MyType>> matrix) {
List<MyType[]> tempRowsList = new LinkedList<>();
for (List<MyType> row : matrix) {
tempRowsList.add(row.toArray(new MyType[row.size()]));
}
return tempRowsList.toArray(new MyType[tempRowsList.size()][]);
}