如何在不使用循环的情况下用Java填充多维数组?我试过:
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没有真正的多维数组。
碰巧,0.0
是Java中doubles的默认值,因此当您从new
中获取矩阵时,该矩阵实际上已经填充了零。然而,如果你想用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);
根据Java 8,我们可以使用这种方式。
double[][] arr = new double[20][4];
Arrays.stream(arr).forEach(a -> Arrays.fill(a, 0));
我们可以用一种更好、更智能的方式初始化多维数组中的值。
OP询问如何在没有循环的情况下解决此问题!出于某种原因,现在流行避免循环。为什么会这样?可能有一种认识是,使用map
、reduce
、filter
和朋友,以及像each
这样的方法可以隐藏循环,减少程序的语言量,而且有点酷。同样适用于真正甜美的Unix管道。或者jQuery代码。没有循环,一切看起来都很棒。
但是Java有map
方法吗?不是这样,但我们可以用eval
或exec
方法定义一个具有Function
接口的接口。这并不太难,是一项很好的锻炼。它可能很昂贵,而且在实践中不使用。
另一种在没有循环的情况下实现的方法是使用尾部递归。是的,这有点傻,也没有人会在实践中使用它,但它确实表明,在这种情况下,循环是可以的。尽管如此,为了展示"又一个无循环的例子"并获得乐趣,这里是:
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填充多维数组?
多维数组只是数组的数组,fill(...)
不会检查数组的类型和传入的值(这一责任由开发人员承担(。
因此,如果不使用循环,就无法很好地填充多维数组。
请注意,与C或C++等语言不同,Java数组是对象,在多维数组中,除了最后一级之外,所有数组都包含对其他Array
对象的引用。我不能100%确定这一点,但它们很可能分布在内存中,因此你不能像C/C++那样只填充一个没有循环的连续块。
作为答案的扩展,我找到了这篇文章,但希望填充一个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);
}
}
};
Arrays.fill适用于一维数组,因此要填充二维数组,我们可以在下进行
for (int i = 0, len = arr.length; i < len; i++)
Arrays.fill(arr[i], 0);
难道我们有时都不希望有一个<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[]
合法且定义明确就好了…(
(使用下面的一个公共方法可以使循环远离调用源代码。
如果您坚持根本不使用循环,请使用递归替换循环和对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);
}
使用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仅适用于一维阵列
java.util.Arrays的来源:
public static void fill(Object[] a, Object val) {
int i = 0;
for(int len = a.length; i < len; ++i) {
a[i] = val;
}
使用自己的循环初始化数组
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不提供这样的API。您需要遍历循环,使用fill方法可以用一个循环填充2D数组
int row = 5;
int col = 6;
int cache[][]=new int[row][col];
for(int i=0;i<=row;i++){
Arrays.fill(cache[i]);
}
递归解决方案
一个简单的递归解决方案,用任何给定的值填充2d数组的每一行。
double[][] arr = new double[20][4];
int n=arr.length;
fillArrRecursively(arr, n-1, 10); //Recursion call
//Recursive method to fill every row of 'arr' with the passed variable 'val'
public static int fillArrRecursively(double arr[][], int n, int val){
if(n<0) return 1;
Arrays.fill(arr[n], val);
return fillArrRecursively(arr, n-1, val);
}
int dis[][]=new int[n][n];
for(int x[]:dis)
Arrays.fill(x,-1);
Arrays.fill(arr, new double[4]);