Tableau.remplir avec le tableau multidimensionnel en Java

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

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

il en résulte java.lang.ArrayStoreException: java.lang.Double

Merci d'avance!

41
demandé sur greybeard 2011-08-19 11:16:29

10 réponses

C'est parce que un double[][] est un tableau de double[] vous ne pouvez pas attribuer 0.0 (il serait comme faire double[] vector = 0.0). En fait, Java n'a pas de véritables tableaux multidimensionnels.

il se trouve Que 0.0 est la valeur par défaut pour les doubles en Java, donc la matrice sera déjà remplie de zéros quand vous l'obtiendrez de new. Toutefois, si vous voulez le remplir avec, par exemple, 1.0 vous pouvez faire ce qui suit:

je ne crois pas que l'API fournit une méthode pour résoudre ceci sans utiliser une boucle. C'est assez simple cependant 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);
74
répondu aioobe 2011-08-19 08:24:01
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);
55
répondu trojanfoe 2011-08-19 07:43:18

L'OP a demandé comment résoudre ce problème sans boucle! Pour une raison quelconque, il est à la mode de nos jours d'éviter les boucles. Pourquoi est-ce? Il y a probablement une prise de conscience que l'utilisation de map,reduce, filter, et les amis, et les méthodes de la forme each Cacher les boucles et couper le programme verbage et sont en quelque sorte cool. Il en va de même pour les pipelines Unix vraiment doux. Ou jQuery. Les choses ont l'air super sans boucles.

mais est-ce que Java a un map méthode? Pas vraiment, mais on pourrait définir une avec un Function interface avec un eval ou exec méthode. Il n'est pas trop dur et serait un bon exercice. Il peut être coûteux et ne pas être utilisé dans la pratique.

une Autre façon de le faire sans boucle est d'utiliser la queue de la récursivité. Oui, c'est une sorte de stupide et ne serait d'utiliser dans la pratique, mais il montre, peut-être, que les boucles sont bien dans ce cas. Néanmoins, juste pour montrer "encore un autre exemple de boucle libre" et d'avoir amusant, ici est la suivante:

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

Il n'est pas assez, mais pour répondre à l'OP de la question, il n'y a pas explicite boucles.

8
répondu Ray Toal 2011-08-19 07:40:55

comment remplir un tableau multidimensionnel en Java sans utiliser une boucle?

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

ainsi vous ne pouvez pas remplir un tableau multidimensionnel raisonnablement bien sans utiliser une boucle.

soyez conscient du fait que, contrairement aux langages comme C ou C++, Les tableaux Java sont des objets et tableaux multidimensionnels tous les niveaux sauf le dernier contiennent des références à d'autres Array objets. Je ne suis pas sûr à 100% de cela, mais très probablement ils sont distribués en mémoire, donc vous ne pouvez pas simplement remplir un bloc contigu sans boucle, comme C/C++ vous permettrait de le faire.

3
répondu Thomas 2011-08-19 07:31:24

comme extension à la réponse, j'ai trouvé ce post mais cherchait à remplir un tableau en 4 dimensions. L'exemple original n'est qu'un tableau bidimensionnel, mais la question dit "multidimensionnel". Je ne voulais pas poster une nouvelle question pour cela...

Vous pouvez utiliser la même méthode, mais vous devez les emboîter de sorte que vous arriviez finalement à un tableau unidimensionnel.

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);
        }
    }
};
1
répondu k3yz101 2013-06-19 06:32:39

ne souhaitons-nous pas tous parfois qu'il y ait un

<T>void java.util.Arrays.deepFill(T[]…multiDimensional). Les problèmes commencent avec

Object threeByThree[][] = new Object[3][3];

threeByThree[1] = null; et

threeByThree[2][1] = new int[]{42}; en étant parfaitement légal.

(Si seulement Object twoDim[]final[] était légal et bien définie...)

(En utilisant l'une des méthodes publiques d'en bas, on conserve les boucles du code source appelant.

Si vous insistez pour utiliser aucune boucle, remplacez les boucles et l'appel par Arrays.fill()(!) utiliser récursivité.)

/** 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);
}
0
répondu greybeard 2016-01-30 10:35:56
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 ce n'bien

0
répondu Ahmed Mazher 2016-03-08 05:47:07

en utilisant Java 8, Vous pouvez déclarer et initialiser un tableau bidimensionnel sans utiliser une 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][]);

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

si vous voulez définir explicitement la valeur de remplissage à utiliser, vous pouvez ajouter un 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
répondu Robby Cornelissen 2017-08-15 06:54:33

en mots simples, java donot fournit une telle API. Vous devez itérer par boucle et en utilisant la méthode de remplissage vous pouvez remplir le 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
répondu Sanjeev Guglani 2018-09-29 03:59:10
Arrays.fill(arr, new double[4]);
-5
répondu watereater 2014-06-25 01:53:57