Qualche scorciatoia per inizializzare tutti gli elementi dell'array a zero?


282

In una C/C++volta

int arr[10] = {0};

... per inizializzare tutti i miei elementi dell'array su 0.

Esiste un collegamento simile in Java?

Voglio evitare di usare il loop, è possibile?

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

2
java.util.Arrays.fill () int [] arr = new int [10]; e int arr [10] = {0}; tutti usano loop interni.
Kevin Kostlan,

Risposte:


574

Un valore predefinito di 0 per le matrici di tipi integrali è garantito dalle specifiche della lingua :

Ciascuna, variabile esempio, o un componente di matrice variabile di classe viene inizializzato con un valore predefinito quando viene creato (§15.9, §15.10) [...] Per il tipo int, il valore di default è zero, cioè, 0.  

Se si desidera inizializzare un array monodimensionale su un valore diverso, è possibile utilizzare java.util.Arrays.fill () (che ovviamente utilizzerà un ciclo internamente).


@MichaelBorgwardt È stata una risposta utile a me. Avrebbe lo stesso costo di farlo rispetto a for loop?
Maytham-ɯɐɥʇʎɐɯ

@ maytham-ɯɐɥıλɐɯ: puoi guardare il codice sorgente, viene fornito con il JDK. È esattamente lo stesso, il metodo consiste in nient'altro che in un loop perfettamente normale e semplice.
Michael Borgwardt,

@MichaelBorgwardt E i valori di un array bidimensionale locale? Questo rientra nel "componente array?"
Rishi,

Arrays.fillnon utilizza necessariamente un ciclo.
NateS,

@NateS: puoi fare un esempio di un'implementazione Java che non lo fa?
Michael Borgwardt,

105

Mentre le altre risposte sono corrette (i valori di array int sono inizializzati per impostazione predefinita su 0), se si desidera farlo in modo esplicito (ad esempio se si desidera un array riempito con il valore 42), è possibile utilizzare il metodo fill () di la classe Array :

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

O se sei un fan di 1-liner, puoi usare la Collections.nCopies()routine:

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

Darebbe ad arr il valore:

[42, 42, 42]

(sebbene sia Integer, e non int, se hai bisogno del tipo primitivo potresti rimandare alla routine di Apache CommonsArrayUtils.toPrimitive() :

int [] primarr = ArrayUtils.toPrimitive(arr);

9
One-liners sono buone, ma List<Integer>per Integer[]a int[]? È un po 'contorto.
Dhardy,

2
@dhardy Certo, ma è per questo che c'è anche la versione a 2 righe nella risposta (se sei preoccupato per il fattore "contorto").
Adam Parkin,

l'inizializzazione dell'array 2d con Arrays.fillmetodo sta creando problemi e si verifica un errore.
AKS

39

In Java tutti gli elementi (tipi interi primitivi byte short, int, long) vengono inizializzati a 0 per default. Puoi salvare il loop.


2
Suppongo che questo valga per i tipi primitivi ?!
Olimpiu POP

1
I tipi java primitivi, come int, non sono inizializzati.
Mirko Ebert,

8
@ tfb785: questo è sbagliato. Come affermato sopra da Michael Borgwardt: i tipi interi primitivi (short, int, long) sono inizializzati su 0.
Arne Deutsch

1
Sì, un array di primitive java come int [] viene avviato con 0. No, un tipo primitivo java non viene avviato con 0.
Mirko Ebert,

3
Ok, per essere precisi: i membri di classe primitivi (siano essi statici o meno) sono inizializzati con 0. Le variabili locali non lo sono.
Arne Deutsch,

23

Come riduce le prestazioni della tua applicazione ....? Leggi di seguito.

Nella specifica del linguaggio Java il valore predefinito / iniziale per qualsiasi oggetto può essere indicato come segue.

Per tipo byte , il valore predefinito è zero , ovvero il valore di (byte) è 0 .

Per il tipo short , il valore predefinito è zero , ovvero il valore di (short) è 0 .

Per tipo int , il valore predefinito è zero , ovvero 0 .

Per tipo long , il valore predefinito è zero , ovvero 0L .

Per il tipo float , il valore predefinito è zero positivo , ovvero 0,0f .

Per il tipo doppio , il valore predefinito è zero positivo , ovvero 0,0 g .

Per il tipo char , il valore predefinito è il carattere null , ovvero " \ u0000 ".

Per il tipo booleano , il valore predefinito è falso .

Per tutti i tipi di riferimento , il valore predefinito è null .

Considerando tutto ciò, non è necessario inizializzare con valori zero per gli elementi dell'array perché, per impostazione predefinita, tutti gli elementi dell'array sono 0 per l'array int.

Perché un array è un oggetto contenitore che contiene un numero fisso di valori di un singolo tipo. Ora il tipo di array per te è int, quindi considera che il valore predefinito per tutti gli elementi dell'array sarà automaticamente 0 Perché contiene int type .

Ora considera l' array per il tipo String in modo che tutti gli elementi dell'array abbiano un valore predefinito sia null .

Perché non farlo ......?

puoi assegnare un valore nullo usando il ciclo come suggerito nella tua domanda.

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

Ma se lo fai, sarà una perdita inutile del ciclo della macchina. e se si utilizza nella propria applicazione in cui sono presenti molti array e lo si fa per ciascun array, ciò influirà sulle prestazioni dell'applicazione fino a un livello considerevole.

Un maggiore utilizzo del ciclo macchina ==> Più tempo per elaborare i dati ==> Il tempo di uscita aumenterà in modo significativo . in modo che l'elaborazione dei dati dell'applicazione possa essere considerata di livello basso (rallenta fino a un certo livello).


17

È possibile salvare il ciclo, l'inizializzazione è già stata fatta su 0. Anche per una variabile locale.

Ma per favore correggi il posto in cui metti le parentesi, per leggibilità (best practice riconosciuta):

int[] arr = new int[10];

14

Se si utilizza Float o Integer, è possibile assegnare un valore predefinito come questo ...

Integer[] data = new Integer[20];
Arrays.fill(data,new Integer(0));

6

È possibile creare un nuovo array vuoto con le dimensioni dell'array esistente e assegnarle nuovamente al proprio array. Questo potrebbe essere più veloce di altri. 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);
    }
}
}

Risultato:

0
0
0
0
0    
0
0
0
0

1

Sì, i valori int in un array sono inizializzati su zero. Ma questo non è garantito. La documentazione Oracle afferma che questa è una cattiva pratica di codifica.


Secondo la specifica del linguaggio Java, sezione 15.10.2 , se un array viene creato con un'eccezione di creazione di array che non fornisce valori iniziali, tutti gli elementi dell'array vengono inizializzati sul valore predefinito per il tipo di componente dell'array, ovvero 0 nel caso di char []. Questa è una garanzia; Sarei piuttosto sorpreso dal fatto che Oracle considerasse basarsi su di essa una cattiva pratica.
Ian Robertson,

1

I valori int sono già zero dopo l'inizializzazione, come tutti hanno già detto. Se si verifica una situazione in cui è necessario impostare i valori di array su zero e si desidera ottimizzarlo, utilizzare 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);

Questo utilizza memcpysotto le coperte nella maggior parte o in tutte le implementazioni di JRE. Si noti che l'uso di uno statico come questo è sicuro anche con più thread, poiché il caso peggiore è la riallocazione di più threadzeros contemporaneamente, il che non danneggia nulla.

Potresti anche usare Arrays.fillcome altri hanno già detto. Arrays.fill potrebbe usarememcpy in una JVM intelligente, ma probabilmente è solo un loop Java e il controllo dei limiti che comporta.

Confronta le tue ottimizzazioni, ovviamente.


1

Ancora un altro approccio usando lambda sopra java 8

 Arrays.stream(new Integer[nodelist.size()]).map(e -> 
 Integer.MAX_VALUE).toArray(Integer[]::new);

1

In c / cpp non c'è scorciatoia ma per inizializzare tutti gli array con il pedice zero.

  int arr[10] = {0};

Ma in java esiste uno strumento magico chiamato Arrays.fill () che riempirà tutti i valori in un array con l'intero di tua scelta.

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

1

L'inizializzazione non è richiesta in caso di zero perché il valore predefinito di int in Java è zero. Per valori diversi da zero java.util.Arraysfornisce una serie di opzioni, il più semplice è il metodo di riempimento.

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]

Possiamo anche usare Arrays.setAll () se vogliamo riempire il valore in base alle condizioni:

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]

0

dichiarare l'array come variabile di istanza nella classe, ovvero fuori da ogni metodo e JVM gli darà 0 come valore predefinito. Non devi più preoccuparti


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

risultato 0123456 -1012345 -2-101234 -3-2-10123 -4-3-2-1012 -5-4-3-2-101 -6-5-4-3-2-10

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.