使用Java中的multidimensional array填充数组

如何在Java中填充multidimensional array而不使用循环? 我试过了:

double[][] arr = new double[20][4]; Arrays.fill(arr, 0); 

这导致java.lang.ArrayStoreException: java.lang.Double

提前致谢!

这是因为double[][]是一个double[]数组,你不能赋值0.0 (这就像做double[] vector = 0.0 )。 事实上,Java没有真正的multidimensional array。

碰巧, 0.0 Java中双精度的默认值 ,因此当你new得到的时候,matrix实际上已经被零填充了。 但是,如果您想填充1.0 ,则可以执行以下操作:

我不相信API提供了一个方法来解决这个问题,而不使用循环。 然而,用for-each循环来做这件事很简单。

 double[][] matrix = new double[20][4]; // Fill each row with 1.0 for (double[] row: matrix) Arrays.fill(row, 1.0); 
 double[][] arr = new double[20][4]; Arrays.fill(arr[0], 0); Arrays.fill(arr[1], 0); Arrays.fill(arr[2], 0); Arrays.fill(arr[3], 0); Arrays.fill(arr[4], 0); Arrays.fill(arr[5], 0); Arrays.fill(arr[6], 0); Arrays.fill(arr[7], 0); Arrays.fill(arr[8], 0); Arrays.fill(arr[9], 0); Arrays.fill(arr[10], 0); Arrays.fill(arr[11], 0); Arrays.fill(arr[12], 0); Arrays.fill(arr[13], 0); Arrays.fill(arr[14], 0); Arrays.fill(arr[15], 0); Arrays.fill(arr[16], 0); Arrays.fill(arr[17], 0); Arrays.fill(arr[18], 0); Arrays.fill(arr[19], 0); 

OP问如何解决这个问题没有一个循环 ! 由于某些原因,现在很stream行避免循环。 为什么是这样? 可能有一个认识,使用mapreducefilter和朋友,像each隐藏循环和减less程序verbage方法,是一种很酷。 Unixpipe道非常甜美。 或者jQuery代码。 事情看起来很好,没有循环。

但是Java有一个map方法吗? 不是真的,但我们可以用一个eval或者exec方法来定义一个带有Function接口的eval 。 这不是太难,会是一个很好的练习。 这可能是昂贵的,并没有在实践中使用。

没有循环的另一种方法是使用尾recursion。 是的,这实在是太傻了,实际上也没有人会用它,但是这确实表明,在这种情况下循环是好的。 尽pipe如此,只是为了展示“又一个循环的例子”,并获得乐趣,这里是:

 import java.util.Arrays; public class FillExample { private static void fillRowsWithZeros(double[][] a, int rows, int cols) { if (rows >= 0) { double[] row = new double[cols]; Arrays.fill(row, 0.0); a[rows] = row; fillRowsWithZeros(a, rows - 1, cols); } } public static void main(String[] args) { double[][] arr = new double[20][4]; fillRowsWithZeros(arr, arr.length - 1, arr[0].length); System.out.println(Arrays.deepToString(arr)); } } 

这不是很好,但是为了回答OP的问题,没有明确的循环。

我怎样才能不使用循环在Java中填充multidimensional array?

multidimensional array只是数组的数组, fill(...)不会检查数组的types和传入的值(这个责任在开发人员身上)。

因此,不能使用循环来合理填充multidimensional array。

请注意,与C或C ++之类的语言不同,Java数组是对象,在multidimensional array中除最后一级外,其他Array都包含对其他Array对象的引用。 我不是100%确定这一点,但很可能他们分布在内存中,所以你不能只填充一个连续的块没有循环,就像C / C ++会允许你做的那样。

作为答案的延伸,我发现这个post,但是正在寻找填充4维数组。 原来的例子只是一个二维数组,但问题是“多维的”。 我不想为此发布新的问题…

您可以使用相同的方法,但是必须将它们嵌套,以便最终获得一维数组。

 fourDArray = new float[10][10][10][1]; // Fill each row with null for (float[][][] row: fourDArray) { for (float[][] innerRow: row) { for (float[] innerInnerRow: innerRow) { Arrays.fill(innerInnerRow, -1000); } } }; 

我们都不希望有一个
<T>void java.util.Arrays.deepFill(T[]…multiDimensional) 。 问题始于
Object threeByThree[][] = new Object[3][3];
threeByThree[1] = null;
threeByThree[2][1] = new int[]{42}; 完全合法。
(如果只有Object twoDim[]final[]是合法的,并且定义得很好…)
(使用下面的公共方法之一从调用源代码保持循环。
如果你坚持不使用循环,用循环replace循环和调用Arrays.fill() (!)。

 /** Fills matrix {@code m} with {@code value}. * @return {@code m}'s dimensionality. * @throws java.lang.ArrayStoreException if the component type * of a subarray of non-zero length at the bottom level * doesn't agree with {@code value}'s type. */ public static <T>int deepFill(Object[] m, T value) { Class<?> components; if (null == m || null == (components = m.getClass().getComponentType())) return 0; int dim = 0; do dim++; while (null != (components = components.getComponentType())); filler((Object[][])m, value, dim); return dim; } /** Fills matrix {@code m} with {@code value}. * @throws java.lang.ArrayStoreException if the component type * of a subarray of non-zero length at level {@code dimensions} * doesn't agree with {@code value}'s type. */ public static <T>void fill(Object[] m, T value, int dimensions) { if (null != m) filler(m, value, dimensions); } static <T>void filler(Object[] m, T value, int toGo) { if (--toGo <= 0) java.util.Arrays.fill(m, value); else for (Object[] subArray : (Object[][])m) if (null != subArray) filler(subArray, value, toGo); } 
 public static Object[] fillArray(Object[] arr,Object item){ Arrays.fill(arr, item); return arr; } Character[][] maze = new Character[10][10]; fillArray(maze, fillArray(maze[0], '?')); for(int i = 0;i<10;i++){ System.out.println(); for(int j = 0;j<10;j++){ System.out.print(maze[i][j]); } } 

我希望这样做很好

使用Java 8,您可以声明并初始化一个二维数组,而不使用(显式)循环,如下所示:

 int x = 20; // first dimension int y = 4; // second dimension double[][] a = IntStream.range(0, x) .mapToObj(i -> new double[y]) .toArray(i -> new double[x][]); 

这将使用默认值初始化数组(如果是double 0.0 )。

如果你想明确定义要使用的填充值,你可以添加一个DoubleStream

 int x = 20; // first dimension int y = 4; // second dimension double v = 5.0; // fill value double[][] a = IntStream .range(0, x) .mapToObj(i -> DoubleStream.generate(() -> v).limit(y).toArray()) .toArray(i -> new double[x][]); 
 Arrays.fill(arr, new double[4]);