web-dev-qa-db-fra.com

Arrays.fill avec un tableau multidimensionnel en Java

Comment remplir un tableau multidimensionnel en Java sans utiliser de boucle? J'ai essayé:

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

Cela se traduit par Java.lang.ArrayStoreException: Java.lang.Double

Merci d'avance!

49
Caroline

Ceci est dû au fait qu'un double[][] est un tableau de double[] auquel vous ne pouvez pas affecter 0.0 (ce serait comme si vous utilisiez double[] vector = 0.0). En fait, Java n'a pas de véritables tableaux multidimensionnels.

En l'occurrence,0.0 est la valeur par défaut de doubles en Java. La matrice sera donc déjà remplie de zéros lorsque vous l'obtenez de new. Cependant, si vous voulez le remplir avec, par exemple, 1.0, vous pouvez procéder comme suit:

Je ne crois pas que l'API fournit une méthode pour résoudre ce problème sans utiliser de boucle. Cependant, il est assez simple de le faire avec une boucle pour chaque boucle.

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

Le PO a demandé comment résoudre ce problème sans boucle! Pour une raison quelconque, il est à la mode ces jours-ci d'éviter les boucles. Pourquoi est-ce? Il est probable que l'on se rend compte que l'utilisation de map, reduce, filter et d'amis, ainsi que des méthodes comme each permettent de masquer les boucles et de réduire le verbage du programme. La même chose vaut pour les très doux pipelines Unix. Ou le code jQuery. Les choses ont fière allure sans boucles.

Mais Java a-t-il une méthode map? Pas vraiment, mais nous pourrions en définir un avec une interface Function avec une méthode eval ou exec. Ce n'est pas trop difficile et serait un bon exercice. Il pourrait être coûteux et non utilisé dans la pratique.

Une autre façon de faire ceci sans boucle consiste à utiliser la récursion de queue. Oui, c'est un peu ridicule et personne ne l'utilisera dans la pratique non plus, mais cela montre peut-être que les boucles sont bonnes dans ce cas. Néanmoins, juste pour montrer "encore un exemple gratuit de boucle" et pour s'amuser, voici:

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

Ce n'est pas joli, mais en réponse à la question du PO, il n'y a pas de boucles explicit.

9
Ray Toal

En guise de prolongement de la réponse, j'ai trouvé ce message mais je cherchais à remplir un tableau à 4 dimensions . L'exemple initial n'est qu'un tableau à deux dimensions, mais la question dit "multidimensionnelle". Je ne voulais pas poster une nouvelle question pour cela ...

Vous pouvez utiliser la même méthode, mais vous devez les imbriquer afin d’obtenir un tableau à une dimension.

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

comment puis-je remplir un tableau multidimensionnel en Java sans utiliser de boucle?

Les tableaux multidimensionnels ne sont que des tableaux de tableaux et fill(...) ne vérifie pas le type du tableau ni la valeur transmise (cette responsabilité incombe au développeur). 

Ainsi, vous ne pouvez pas remplir un tableau multidimensionnel raisonnablement bien sans utiliser de boucle.

Sachez que, contrairement aux langages tels que C ou C++, les tableaux Java sont des objets et, dans les tableaux multidimensionnels, tous les éléments sauf le dernier niveau contiennent des références à d'autres objets Array. Je ne suis pas tout à fait sûr à ce sujet, mais ils sont probablement distribués en mémoire. Vous ne pouvez donc pas simplement remplir un bloc contigu sans boucle, comme le permet le C/C++.

3
Thomas

Selon Java 8, nous pouvons utiliser cette méthode. 

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

Nous pouvons initialiser une valeur dans un tableau multidimensionnel de manière plus élégante et intelligente. 

2
Bipool

Avec Java 8, vous pouvez déclarer et initialiser un tableau à deux dimensions sans utiliser de boucle (explicite) comme suit:

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

Cela initialisera les tableaux avec les valeurs par défaut (0.0 dans le cas de double).

Si vous souhaitez définir explicitement la valeur de remplissage à utiliser, vous pouvez ajouter une variable 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][]);
0
Robby Cornelissen
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]);
        }
    }

j'espère que ça va bien

0
Ahmed Mazher

En termes simples, Java ne fournit pas une telle API . Vous devez parcourir une boucle et utiliser la méthode de remplissage pour remplir un tableau 2D avec une boucle.

      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