Un raccourci pour initialiser tous les éléments du tableau à zéro?

282

Dans C/C++je faisais

int arr[10] = {0};

... pour initialiser tous mes éléments de tableau à 0.

Existe-t-il un raccourci similaire en Java?

Je veux éviter d'utiliser la boucle, est-ce possible?

int arr[] = new int[10];
for(int i = 0; i < arr.length; i++) {
    arr[i] = 0;
}
jeu terminé
la source
2
java.util.Arrays.fill () int [] arr = new int [10]; et int arr [10] = {0}; tous utilisent des boucles internes.
Kevin Kostlan

Réponses:

574

Une valeur par défaut de 0 pour les tableaux de types intégraux est garantie par la spécification du langage :

Chaque variable de classe, variable d'instance, ou d'un composant de tableau est initialisé avec une valeur par défaut lors de sa création (§15.9, §15.10) [...] Pour le type int, la valeur par défaut est égale à zéro, c'est 0.  

Si vous souhaitez initialiser un tableau unidimensionnel à une valeur différente, vous pouvez utiliser java.util.Arrays.fill () (qui utilisera bien sûr une boucle en interne).

Michael Borgwardt
la source
@MichaelBorgwardt m'a été une réponse utile. Est-ce que cela aurait le même coût de le faire par rapport à la boucle for?
maytham-ɯɐɥʇʎɐɯ
@ maytham-ɯɐɥıλɐɯ: vous pouvez regarder le code source, il est livré avec le JDK. C'est exactement la même chose, la méthode consiste en rien d'autre qu'une boucle parfaitement normale et simple pour.
Michael Borgwardt
@MichaelBorgwardt Qu'en est-il des valeurs d'un tableau local à 2 dimensions? Est-ce que cela relève du «composant de tableau»
Rishi
Arrays.filln'utilise pas nécessairement une boucle.
NateS
@NateS: pouvez-vous donner un exemple d'une implémentation Java qui ne fonctionne pas?
Michael Borgwardt
105

Alors que les autres réponses sont correctes (les valeurs de tableau int sont par défaut initialisées à 0), si vous vouliez le faire explicitement (par exemple si vous vouliez un tableau rempli avec la valeur 42), vous pouvez utiliser la méthode fill () de la classe Arrays :

int [] myarray = new int[num_elts];
Arrays.fill(myarray, 42);

Ou si vous êtes un fan de 1-liners, vous pouvez utiliser la Collections.nCopies()routine:

Integer[] arr = Collections.nCopies(3, 42).toArray(new Integer[0]);

Donnerait à arr la valeur:

[42, 42, 42]

(bien que ce soit le cas Integer, et non int, si vous avez besoin du type primitif, vous pouvez vous en remettre à la routine Apache CommonsArrayUtils.toPrimitive() :

int [] primarr = ArrayUtils.toPrimitive(arr);
Adam Parkin
la source
9
Sont bonnes, mais une seule ligne List<Integer>à Integer[]la int[]? C'est un peu compliqué.
dhardy
2
@dhardy Bien sûr, mais c'est pourquoi il y a aussi la version à 2 lignes dans la réponse (si vous êtes préoccupé par le facteur "alambiqué").
Adam Parkin
l'initialisation du tableau 2D avec la Arrays.fillméthode crée un problème et une erreur se produit.
AKS
39

Dans java tous les éléments (types entiers primitifs byte short, int, long) sont initialisés à 0 par défaut. Vous pouvez enregistrer la boucle.

Arne Deutsch
la source
2
Je suppose que cela vaut pour les types primitifs?!
Olimpiu POP
1
Les types java primitifs, comme int, ne sont pas initialisés.
Mirko Ebert
8
@ tfb785: C'est faux. Comme indiqué ci-dessus par Michael Borgwardt: les types entiers primitifs (court, entier, long) sont initialisés à 0.
Arne Deutsch
1
Oui, un tableau de primitives java comme int [] est initié avec 0. Non, un type de primitive java n'est pas initié avec 0.
Mirko Ebert
3
Ok, pour être précis: les membres de classe primitifs (qu'ils soient statiques ou non) sont initialisés avec 0. Les variables locales ne le sont pas.
Arne Deutsch
23

Comment cela réduit les performances de votre application ....? Lire la suite.

Dans la spécification du langage Java, la valeur par défaut / initiale de tout objet peut être indiquée comme suit.

Pour l' octet de type , la valeur par défaut est zéro , c'est-à-dire que la valeur de (octet) est 0 .

Pour le type court , la valeur par défaut est zéro , c'est-à-dire que la valeur de (court) est 0 .

Pour le type int , la valeur par défaut est zéro , c'est-à-dire 0 .

Pour le type long , la valeur par défaut est zéro , c'est-à-dire 0L .

Pour le type float , la valeur par défaut est un zéro positif , c'est-à-dire 0,0f .

Pour le type double , la valeur par défaut est zéro positif , c'est-à-dire 0,0d .

Pour le type char , la valeur par défaut est le caractère nul , c'est-à-dire ' \ u0000 '.

Pour le type booléen , la valeur par défaut est false .

Pour tous les types de référence , la valeur par défaut est null .

En considérant tout cela, vous n'avez pas besoin d'initialiser avec des valeurs nulles pour les éléments du tableau car par défaut, tous les éléments du tableau sont à 0 pour le tableau int.

Parce qu'un tableau est un objet conteneur qui contient un nombre fixe de valeurs d'un seul type. Maintenant, le type de tableau pour vous est int, alors considérez que la valeur par défaut pour tous les éléments du tableau sera automatiquement 0 car il contient un type int .

Considérez maintenant le tableau pour le type String afin que tous les éléments du tableau aient la valeur par défaut est null .

Pourquoi ne fais pas ça ......?

vous pouvez attribuer une valeur nulle en utilisant la boucle comme vous le suggérez dans votre question.

int arr[] = new int[10];
for(int i=0;i<arr.length;i++)
    arr[i] = 0;

Mais si vous le faites, cela entraînera une perte inutile du cycle de la machine. et si vous utilisez dans votre application où vous avez de nombreux tableaux et que vous le faites pour chaque tableau, cela affectera les performances de l'application jusqu'à un niveau considérable.

L'utilisation accrue du cycle machine ==> Plus de temps pour traiter les données ==> Le temps de sortie sera considérablement augmenté . afin que le traitement des données de votre application puisse être considéré comme un niveau bas (Ralentir jusqu'à un certain niveau).

Jugal Thakkar
la source
17

Vous pouvez enregistrer la boucle, l'initialisation est déjà effectuée à 0. Même pour une variable locale.

Mais veuillez corriger l'endroit où vous placez les crochets, pour plus de lisibilité (meilleure pratique reconnue):

int[] arr = new int[10];
KLE
la source
14

Si vous utilisez Float ou Integer, vous pouvez attribuer une valeur par défaut comme celle-ci ...

Integer[] data = new Integer[20];
Arrays.fill(data,new Integer(0));
Pankaj Goyal
la source
6

Vous pouvez créer un nouveau tableau vide avec votre taille de tableau existante et vous pouvez les attribuer à votre tableau. Cela peut être plus rapide que les autres. Snipet:

package com.array.zero;
public class ArrayZero {
public static void main(String[] args) {
    // Your array with data
    int[] yourArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    //Creating same sized array with 0
    int[] tempArray = new int[yourArray.length];
    Assigning temp array to replace values by zero [0]
    yourArray = tempArray;

    //testing the array size and value to be zero
    for (int item : yourArray) {
        System.out.println(item);
    }
}
}

Résultat :

0
0
0
0
0    
0
0
0
0
Kavishankar Karunakaran
la source
1

Oui, les valeurs int d'un tableau sont initialisées à zéro. Mais ce n'est pas garanti. La documentation Oracle indique qu'il s'agit d'une mauvaise pratique de codage.

nate
la source
Selon la spécification du langage Java, section 15.10.2 , si un tableau est créé avec une exception de création de tableau qui ne fournit pas de valeurs initiales, tous les éléments du tableau sont initialisés à la valeur par défaut pour le type de composant du tableau - c'est-à-dire 0 dans le cas de char []. Ceci est une garantie; Je serais assez surpris qu'Oracle considère que le fait de compter dessus soit une mauvaise pratique.
Ian Robertson
1

Les valeurs int sont déjà nulles après l'initialisation, comme tout le monde l'a mentionné. Si vous avez une situation où vous devez réellement définir des valeurs de tableau à zéro et que vous souhaitez optimiser cela, utilisez System.arraycopy:

static private int[] zeros = new float[64];
...
int[] values = ...
if (zeros.length < values.length) zeros = new int[values.length];
System.arraycopy(zeros, 0, values, 0, values.length);

Cela utilise memcpysous les couvertures dans la plupart ou toutes les implémentations JRE. Notez que l'utilisation d'une statique comme celle-ci est sûre même avec plusieurs threads, car le pire des cas est la réallocation de plusieurs threadszeros simultanée de , ce qui ne fait rien de mal.

Vous pouvez également utiliser Arrays.fillcomme d'autres l'ont mentionné. Arrays.fill pourrait utilisermemcpy dans une JVM intelligente, mais n'est probablement qu'une boucle Java et la vérification des limites que cela implique.

Benchmarkez vos optimisations, bien sûr.

NateS
la source
1

Encore une autre approche en utilisant lambda au-dessus de java 8

 Arrays.stream(new Integer[nodelist.size()]).map(e -> 
 Integer.MAX_VALUE).toArray(Integer[]::new);
brahmananda Kar
la source
1

Dans c / cpp il n'y a pas de raccourci mais pour initialiser tous les tableaux avec l'indice zéro.

  int arr[10] = {0};

Mais en java, il existe un outil magique appelé Arrays.fill () qui remplira toutes les valeurs d'un tableau avec l'entier de votre choix.

  import java.util.Arrays;

    public class Main
    {
      public static void main(String[] args)
       {
         int ar[] = {2, 2, 1, 8, 3, 2, 2, 4, 2};
         Arrays.fill(ar, 10);
         System.out.println("Array completely filled" +                          
            " with 10\n" + Arrays.toString(ar));
   }
 }
Ansh Srivastava
la source
1

L'initialisation n'est pas requise en cas de zéro car la valeur par défaut de int en Java est zéro. Pour les valeurs autres que zéro, java.util.Arraysplusieurs options sont disponibles, la plus simple étant la méthode fill.

int[] arr = new int[5];
Arrays.fill(arr, -1);
System.out.println(Arrays.toString(arr));  //[-1, -1, -1, -1, -1 ]

int [] arr = new int[5];
// fill value 1 from index 0, inclusive, to index 3, exclusive
Arrays.fill(arr, 0, 3, -1 )
System.out.println(Arrays.toString(arr)); // [-1, -1, -1, 0, 0]

Nous pouvons également utiliser Arrays.setAll () si nous voulons remplir la valeur sous condition:

int[] array = new int[20];
Arrays.setAll(array, p -> p > 10 ? -1 : p);

int[] arr = new int[5];
Arrays.setAll(arr, i -> i);
System.out.println(Arrays.toString(arr));   // [0, 1, 2, 3, 4]
Shreya Sharma
la source
0

déclarer le tableau comme variable d'instance dans la classe, c'est-à-dire hors de chaque méthode et JVM lui donnera 0 comme valeur par défaut. Vous ne devez plus vous inquiéter

Dhruvam Gupta
la source
-3
    int a=7, b=7 ,c=0,d=0;
    int dizi[][]=new int[a][b];
    for(int i=0;i<a;i++){
        for(int q=d;q<b;q++){
            dizi[i][q]=c;               
            System.out.print(dizi[i][q]);
            c++;
        }

        c-=b+1;
        System.out.println();               
    }

résultat 0123456 -1012345 -2-101234 -3-2-10123 -4-3-2-1012 -5-4-3-2-101 -6-5-4-3-2-10

Ubeyd
la source