java中多维数组的arrays.fill

irtuqstp  于 2021-06-30  发布在  Java
关注(0)|答案(13)|浏览(571)

如何在java中填充多维数组而不使用循环?我试过:

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

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

eh57zj3b

eh57zj3b1#

如何在java中填充多维数组而不使用循环?
多维数组只是数组和 fill(...) 不检查数组的类型和传入的值(这由开发人员负责)。
因此,如果不使用循环,就无法很好地填充多维数组。
请注意,与c或c等语言不同,java数组是对象,在多维数组中,除了最后一级之外,所有数组都包含对其他数组的引用 Array 物体。我不是100%确定,但它们很可能分布在内存中,因此不能像c/c允许的那样,只填充没有循环的连续块。

h7appiyu

h7appiyu2#

这是因为 double[][] 是一个数组 double[] 你不能分配 0.0 这就像 double[] vector = 0.0 ). 事实上,java没有真正的多维数组。
碰巧的是, 0.0 是java中double的默认值,因此从 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);
2vuwiymt

2vuwiymt3#

简单地说,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]);
      }
yc0p9oo0

yc0p9oo04#

使用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][]);

这将用默认值初始化数组( 0.0 如果是 double ).
如果要显式定义要使用的填充值,可以添加 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][]);
yhived7q

yhived7q5#

我们不是有时候都希望 <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);
}
woobm2wo

woobm2wo6#

fill与一维数组一起工作,所以要填充二维数组,我们可以在下面做

for (int i = 0, len = arr.length; i < len; i++)
    Arrays.fill(arr[i], 0);
7kjnsjlb

7kjnsjlb7#

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);
crcmnpdw

crcmnpdw8#

操作询问如何解决这个问题没有一个循环!出于某种原因,现在流行避免循环。为什么会这样?也许有一种意识 map , reduce , filter ,和朋友,还有像 each 隐藏循环,减少程序的冗长,有点酷。这同样适用于真正甜美的unix管道。或jquery代码。没有环的东西看起来很好。
但是java有一个 map 方法?不是,但我们可以用 Functioneval 或者 exec 方法。这不太难,是个很好的锻炼。这可能是昂贵的,而不是在实践中使用。
另一种不用循环的方法是使用尾部递归。是的,这有点傻,没有人会在实践中使用它,但它确实表明,也许,循环在这种情况下是好的。尽管如此,为了展示“又一个无循环示例”并获得乐趣,以下是:

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问题的回答,这里没有显式循环。

7hiiyaii

7hiiyaii9#

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;
        }

使用自己的循环初始化数组

eqfvzcg8

eqfvzcg810#

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]);
        }
    }

我希望这一切顺利

bogh5gae

bogh5gae11#

Arrays.fill(arr, new double[4]);
bmvo0sr5

bmvo0sr512#

根据Java8,我们可以使用这种方法。 double[][] arr = new double[20][4]; Arrays.stream(arr).forEach(a -> Arrays.fill(a, 0)); 我们可以用一种更好、更智能的方式初始化多维数组中的值。

qxsslcnc

qxsslcnc13#

作为答案的延伸,我找到了这篇文章,但我想填充一个四维数组。最初的例子只是一个二维数组,但问题是“多维的”。我不想为此提出新问题。。。
可以使用相同的方法,但必须嵌套它们,以便最终得到一维数组。

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);
        }
    }
};

相关问题