Java 中的 Arrays.fill 多维数组

发布于 2024-11-30 12:19:50 字数 196 浏览 0 评论 0原文

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

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

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

How can I fill a multidimensional array in Java without using a loop? I've tried:

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

This results in java.lang.ArrayStoreException: java.lang.Double

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

早茶月光 2024-12-07 12:19:50

这是因为 double[][] 是一个 double[] 数组,您不能将 0.0 分配给它(就像执行double[]向量= 0.0)。事实上,Java没有真正的多维数组。

碰巧,0.0 是 Java 中双精度数的默认值,因此当您从 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);

This is because a double[][] is an array of double[] which you can't assign 0.0 to (it would be like doing double[] vector = 0.0). In fact, Java has no true multidimensional arrays.

As it happens, 0.0 is the default value for doubles in Java, thus the matrix will actually already be filled with zeros when you get it from new. However, if you wanted to fill it with, say, 1.0 you could do the following:

I don't believe the API provides a method to solve this without using a loop. It's simple enough however to do it with a for-each loop.

double[][] matrix = new double[20][4];

// Fill each row with 1.0
for (double[] row: matrix)
    Arrays.fill(row, 1.0);
晚雾 2024-12-07 12:19:50
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);
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);
左耳近心 2024-12-07 12:19:50

按照 Java 8,我们可以使用这种方式。

double[][] arr = new double[20][4];
Arrays.stream(arr).forEach(a -> Arrays.fill(a, 0));

我们可以用更好更智能的方式初始化多维数组中的值。

As Per Java 8, we can use this way.

double[][] arr = new double[20][4];
Arrays.stream(arr).forEach(a -> Arrays.fill(a, 0));

We can initialize a value in multidimensional array in a nicer and smart way.

溺渁∝ 2024-12-07 12:19:50

OP询问如何解决这个问题没有循环!出于某种原因,现在避免循环很流行。这是为什么呢?可能已经意识到使用 mapreducefilter 和朋友以及 each 等方法隐藏循环减少程序中的废话,这很酷。这同样适用于真正甜蜜的 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的问题,没有显式循环。

The OP asked how to solve this problem without a loop! For some reason it is fashionable these days to avoid loops. Why is this? Probably there is a realization that using map, reduce, filter, and friends, and methods like each hide loops and cut down on program verbage and are kind of cool. The same goes for really sweet Unix pipelines. Or jQuery code. Things just look great without loops.

But does Java have a map method? Not really, but we could define one with a Function interface with an eval or exec method. It isn't too hard and would be a good exercise. It might be expensive and not used in practice.

Another way to do this without a loop is to use tail recursion. Yes, it is kind of silly and no one would use it in practice either, but it does show, maybe, that loops are fine in this case. Nevertheless, just to show "yet another loop free example" and to have fun, here is:

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

It isn't pretty, but in answer to the OP's question, there are no explicit loops.

梦过后 2024-12-07 12:19:50

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

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

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

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

how can I fill a multidimensional array in Java without using a loop?

Multidimensional arrays are just arrays of arrays and fill(...) doesn't check the type of the array and the value you pass in (this responsibility is upon the developer).

Thus you can't fill a multidimensional array reasonably well without using a loop.

Be aware of the fact that, unlike languages like C or C++, Java arrays are objects and in multidimensional arrays all but the last level contain references to other Array objects. I'm not 100% sure about this, but most likely they are distributed in memory, thus you can't just fill a contiguous block without a loop, like C/C++ would allow you to do.

不知在何时 2024-12-07 12:19:50

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

As an extension to the answer, I found this post but was looking to fill a 4 dimensional array.
The original example is only a two dimensional array, but the question says "multidimensional". I didn't want to post a new question for this...

You can use the same method, but you have to nest them so that you eventually get to a single dimensional array.

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);
        }
    }
};
深爱成瘾 2024-12-07 12:19:50

Arrays.fill 适用于一维数组,因此要填充二维数组,我们可以执行以下操作

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

Arrays.fill works with single dimensional array, so to fill two dimensional array we can do below

for (int i = 0, len = arr.length; i < len; i++)
    Arrays.fill(arr[i], 0);
浅暮の光 2024-12-07 12:19:50

我们有时不都希望有一个
void java.util.Arrays.deepFill(T[]…multiDimensional)。问题始于
对象三ByThree[][] = new Object[3][3];
twoByThree[1] = null;
twoByThree[2][1] = new int[]{42}; 完全合法。
(如果只有 ObjecttwoDim[]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);
}

Don't we all sometimes wish there was a
<T>void java.util.Arrays.deepFill(T[]…multiDimensional). Problems start with
Object threeByThree[][] = new Object[3][3];
threeByThree[1] = null; and
threeByThree[2][1] = new int[]{42}; being perfectly legal.
(If only Object twoDim[]final[] was legal and well defined…)
(Using one of the public methods from below keeps loops from the calling source code.
If you insist on using no loops at all, substitute the loops and the call to Arrays.fill()(!) using recursion.)

/** 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);
}
恰似旧人归 2024-12-07 12:19:50

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

Using Java 8, you can declare and initialize a two-dimensional array without using a (explicit) loop as follows:

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

This will initialize the arrays with default values (0.0 in the case of double).

In case you want to explicitly define the fill value to be used, You can add in a 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][]);
彡翼 2024-12-07 12:19:50

简单来说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]);
      }

In simple words java donot provide such an API.
You need to iterate through loop and using fill method you can fill 2D array with one loop.

      int row = 5;
      int col = 6;
      int cache[][]=new int[row][col];
      for(int i=0;i<=row;i++){
          Arrays.fill(cache[i]);
      }
宛菡 2024-12-07 12:19:50

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

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

Arrays.fill works only with one-dimensional array

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

Use own loops for initialization array

厌倦 2024-12-07 12:19:50
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]);
        }
    }

我希望这一切顺利

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

i hope this do well

初见终念 2024-12-07 12:19:50

递归解决方案

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

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

Recursive Solution

A simple Recursive Solution to fill every row of a 2d array with any given value.

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);
}
太阳男子 2024-12-07 12:19:50
     int dis[][]=new int[n][n];
     for(int x[]:dis)
        Arrays.fill(x,-1);
     
     int dis[][]=new int[n][n];
     for(int x[]:dis)
        Arrays.fill(x,-1);
     
夏九 2024-12-07 12:19:50
Arrays.fill(arr, new double[4]);
Arrays.fill(arr, new double[4]);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文