wake-up-neo.com

Arrays.Fill mit mehrdimensionalem Array in Java

Wie kann ich ein mehrdimensionales Array in Java füllen, ohne eine Schleife zu verwenden? Ich habe es versucht:

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

Dies führt zu Java.lang.ArrayStoreException: Java.lang.Double

Danke im Voraus!

49
Caroline

Dies liegt daran, dass ein double[][] ein Array von double[] ist, dem Sie 0.0 nicht zuweisen können (es wäre, als würden Sie double[] vector = 0.0 tun). Java hat tatsächlich keine echten mehrdimensionalen Arrays.

Zufällig ist0.0 der Standardwert für double in Java. Daher wird die Matrix bereits mit Nullen gefüllt, wenn Sie sie von new erhalten. Wenn Sie es jedoch mit 1.0 füllen möchten, können Sie Folgendes tun:

Ich glaube nicht, dass die API eine Methode bietet, um dieses Problem zu lösen, ohne eine Schleife zu verwenden. Es ist jedoch einfach genug, um es mit einer for-each-Schleife zu tun.

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

// Fill each row with 1.0
for (double[] row: matrix)
    Arrays.fill(row, 1.0);
80
aioobe
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);
56
trojanfoe

Das OP hat gefragt, wie man dieses Problem lösen kann ohne Schleife! Aus irgendeinem Grund ist es heutzutage in Mode, Schleifen zu vermeiden. Warum ist das? Wahrscheinlich gibt es eine Erkenntnis, dass die Verwendung von map, reduce, filter und Freunden und Methoden wie each Schleifen verbergen und Programmverbote einschränken und irgendwie cool sind. Das gleiche gilt für wirklich süße Unix-Pipelines. Oder jQuery-Code. Die Dinge sehen ohne Schleifen einfach gut aus.

Aber hat Java eine map-Methode? Nicht wirklich, aber wir könnten eine mit einer Function-Schnittstelle mit einer eval- oder exec-Methode definieren. Es ist nicht zu schwer und wäre eine gute Übung. Es ist möglicherweise teuer und wird in der Praxis nicht verwendet.

Eine andere Möglichkeit, dies ohne Schleife zu tun, ist die Verwendung der Endrekursion. Ja, es ist irgendwie dumm und niemand würde es in der Praxis auch benutzen, aber es zeigt vielleicht, dass Schleifen in diesem Fall in Ordnung sind. Nur um "noch ein weiteres schleifenfreies Beispiel" zu zeigen und Spaß zu haben, hier ist:

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

Es ist nicht schön, aber als Antwort auf die Frage des OP gibt es keine expliziten Schleifen.

9
Ray Toal

Als Erweiterung der Antwort fand ich diesen Beitrag, wollte aber ein 4-dimensionales Array füllen .. Das ursprüngliche Beispiel ist nur ein zweidimensionales Array, aber die Frage lautet "multidimensional". Ich wollte keine neue Frage dazu posten ...

Sie können dieselbe Methode verwenden, müssen jedoch verschachtelt werden, um schließlich zu einem eindimensionalen Array zu gelangen.

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

wie kann ich ein mehrdimensionales Array in Java füllen, ohne eine Schleife zu verwenden?

Mehrdimensionale Arrays sind nur Arrays von Arrays, und fill(...) überprüft nicht den Typ des Arrays und den Wert, den Sie übergeben (dies liegt beim Entwickler). 

Daher können Sie ein mehrdimensionales Array ohne eine Schleife nicht ausreichend füllen.

Beachten Sie, dass Java-Arrays im Gegensatz zu Sprachen wie C oder C++ Objekte sind. In mehrdimensionalen Arrays enthalten alle außer der letzten Ebene Verweise auf andere Array-Objekte. Ich bin mir nicht zu 100% sicher, aber höchstwahrscheinlich sind sie im Arbeitsspeicher verteilt. Daher können Sie einen zusammenhängenden Block nicht ohne Schleife füllen, wie es C/C++ zulässt.

3
Thomas

Als Per Java 8 können wir diesen Weg verwenden. 

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

Wir können einen Wert in einem mehrdimensionalen Array auf eine schönere und intelligentere Weise initialisieren. 

2
Bipool

Wünschen wir uns nicht alle manchmal, es gäbe eine
<T>void Java.util.Arrays.deepFill(T[]…multiDimensional). Probleme beginnen mit
Object threeByThree[][] = new Object[3][3];
threeByThree[1] = null; Und
threeByThree[2][1] = new int[]{42}; Ist vollkommen legal.
(Wenn nur Object twoDim[]final[] Legal und genau definiert wäre ...)
(Mit einer der folgenden öffentlichen Methoden werden Schleifen vom aufrufenden Quellcode ferngehalten.
Wenn Sie darauf bestehen, überhaupt keine Schleifen zu verwenden, ersetzen Sie die Schleifen und den Aufruf von Arrays.fill() (!) Durch Rekursion.)

/** 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);
}
1
greybeard

Mit Java 8 können Sie ein zweidimensionales Array deklarieren und initialisieren, ohne eine (explizite) Schleife wie folgt zu verwenden:

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

Dies initialisiert die Arrays mit Standardwerten (0.0 im Fall von double).

Wenn Sie den zu verwendenden Füllwert explizit definieren möchten, können Sie eine DoubleStream hinzufügen:

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

ich hoffe, dass es gut geht

0
Ahmed Mazher

Mit einfachen Worten stellt Java donot eine solche API bereit. Sie müssen die Schleife durchlaufen und mithilfe der Füllmethode können Sie das 2D-Array mit einer Schleife füllen.

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