繁体   English   中英

Arrays.fill 用 Ja​​va 中的多维数组

[英]Arrays.fill with multidimensional array in Java

如何在不使用循环的情况下在 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.0Java 中双精度数的默认值,因此当您从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询问如何在没有循环的情况下解决此问题! 出于某种原因,如今避免循环很流行。 为什么是这样? 可能有一种认识,使用mapreducefilter和朋友,以及each hide 循环和减少程序冗长的方法,有点酷。 这同样适用于真正甜蜜的 Unix 管道。 或 jQuery 代码。 没有循环的东西看起来很棒。

但是Java有map方法吗? 不是真的,但我们可以定义一个带有evalexec方法的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 的问题时,没有明确的循环。

作为答案的扩展,我找到了这篇文章,但希望填充一个 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);
        }
    }
};

如何在不使用循环的情况下在 Java 中填充多维数组?

多维数组只是数组的数组,而fill(...)不检查数组的类型和传入的值(此责任由开发人员承担)。

因此,如果不使用循环,就无法合理地填充多维数组。

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

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。 您需要遍历循环并使用填充方法可以用一个循环填充二维数组。

      int row = 5;
      int col = 6;
      int cache[][]=new int[row][col];
      for(int i=0;i<=row;i++){
          Arrays.fill(cache[i]);
      }

递归解

一个简单的递归解决方案,用任何给定的值填充二维数组的每一行。

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);
}
Arrays.fill(arr, new double[4]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM