Gibt es eine Verknüpfung, um alle Array-Elemente auf Null zu initialisieren?

281

In C/C++Früher habe ich tun

int arr[10] = {0};

... um alle meine Array-Elemente auf 0 zu initialisieren.

Gibt es eine ähnliche Verknüpfung in Java?

Ich möchte die Verwendung der Schleife vermeiden. Ist das möglich?

int arr[] = new int[10];
for(int i = 0; i < arr.length; i++) {
    arr[i] = 0;
}
Spiel ist aus
quelle
2
java.util.Arrays.fill () int [] arr = new int [10]; und int arr [10] = {0}; Alle verwenden interne Schleifen.
Kevin Kostlan

Antworten:

574

Ein Standardwert von 0 für Arrays integraler Typen wird durch die Sprachspezifikation garantiert :

Jede Klassenvariable, Instanzvariable oder Array-Komponente wird beim Erstellen mit einem Standardwert initialisiert (§15.9, §15.10). [...] Für den Typ intist der Standardwert Null, d. H.0 .  

Wenn Sie ein eindimensionales Array mit einem anderen Wert initialisieren möchten, können Sie java.util.Arrays.fill () verwenden (wobei natürlich intern eine Schleife verwendet wird).

Michael Borgwardt
quelle
@ MichaelBorgwardt War eine hilfreiche Antwort auf mich. Hätte das im Vergleich zu for loop die gleichen Kosten?
Maytham-ɯɐɥʇʎɐɯ
@ maytham-ɯɐɥıλɐɯ: Sie können sich den Quellcode ansehen, er wird mit dem JDK geliefert. Es ist genau das gleiche, die Methode besteht nur aus einer völlig normalen, unkomplizierten for-Schleife.
Michael Borgwardt
@MichaelBorgwardt Was ist mit den Werten eines lokalen zweidimensionalen Arrays? Fällt das unter "Array-Komponente"?
Rishi
Arrays.fillverwendet nicht unbedingt eine Schleife.
NateS
@NateS: Können Sie ein Beispiel für eine Java-Implementierung geben, die dies nicht tut?
Michael Borgwardt
104

Während die anderen Antworten korrekt sind (int-Array-Werte werden standardmäßig auf 0 initialisiert), können Sie die fill () -Methode von verwenden, wenn Sie dies explizit tun möchten (z. B. wenn Sie beispielsweise ein Array mit dem Wert 42 möchten) die Arrays- Klasse:

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

Oder wenn Sie ein Fan von 1-Liner sind, können Sie die Collections.nCopies()Routine verwenden:

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

Würde arr den Wert geben:

[42, 42, 42]

(obwohl dies der Fall Integerist und nicht int, wenn Sie den primitiven Typ benötigen, können Sie die Apache Commons-ArrayUtils.toPrimitive() Routine verwenden:

int [] primarr = ArrayUtils.toPrimitive(arr);
Adam Parkin
quelle
9
Einzeiler sind gut, aber List<Integer>zu Integer[]zu int[]? Das ist ein bisschen verworren.
Dhardy
2
@dhardy Sicher, aber deshalb gibt es auch die 2-Zeilen-Version in der Antwort (wenn Sie über den "verschlungenen" Faktor besorgt sind).
Adam Parkin
Das Initialisieren des 2d-Arrays mit der Arrays.fillMethode führt zu Problemen und Fehlern.
AKS
39

In Java alle Elemente (primitive Typen integer byte short, int, long) sind standardmäßig auf 0 initialisiert. Sie können die Schleife speichern.

Arne Deutsch
quelle
2
Ich nehme an, das gilt für die primitiven Typen?!
Olimpiu POP
1
Primitive Java-Typen wie int werden nicht initialisiert.
Mirko Ebert
8
@ tfb785: Das ist falsch. Wie oben von Michael Borgwardt angegeben: Primitive Integer-Typen (kurz, int, lang) werden auf 0 initialisiert.
Arne Deutsch
1
Ja, Array von Java-Primitiven wie int [] werden mit 0 initiiert. Nein, ein Java-Primitiv-Typ wird nicht mit 0 initiiert.
Mirko Ebert
3
Ok, um genau zu sein: Primitive Klassenmitglieder (ob statisch oder nicht) werden mit 0 initialisiert. Lokale Variablen sind es nicht.
Arne Deutsch
23

Wie reduziert es die Leistung Ihrer Anwendung ....? Lesen Sie Folgendes.

In der Java-Sprachspezifikation den Standard- / Anfangswert für jedes Objekt wie folgt angegeben werden.

Für Typ - Byte , der Standardwert ist Null , das heißt, ist der Wert von (Byte) 0 .

Für Typen Kurz der Standardwert ist Null , das heißt, ist der Wert von (kurzen) 0 .

Für den Typ int , der Standardwert ist Null , das heißt, 0 .

Für Typ lange der Standardwert ist Null , das heißt, 0L .

Für Typ float , der Standardwert ist positiv Null , das ist 0.0f .

Für Typ double , der Standardwert ist positiv Null , das heißt, 0.0d .

Für Typ char ist der Standardwert das Nullzeichen , dh ' \ u0000 '.

Für den Typ boolean , der Standardwert ist falsch .

Zum alle Referenztypen , der Standardwert ist null .

Wenn Sie all dies berücksichtigen, müssen Sie nicht mit Nullwerten für die Array-Elemente initialisieren, da standardmäßig alle Array-Elemente für das int-Array 0 sind.

Weil ein Array ein Containerobjekt ist, das eine feste Anzahl von Werten eines einzelnen Typs enthält. Nun ist der Array-Typ für Sie int. dass der Standardwert für alle Array-Elemente automatisch 0 ist , da er den Typ int enthält .

Nun betrachten Sie die Array für String - Typen , so dass alle Array - Elemente haben Standardwert ist null .

Warum machst du das nicht ......?

Sie können einen Nullwert zuweisen, indem Sie die Schleife verwenden, wie Sie in Ihrer Frage vorschlagen.

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

Wenn Sie dies jedoch tun, führt dies zu einem nutzlosen Verlust des Maschinenzyklus. Wenn Sie in Ihrer Anwendung viele Arrays verwenden und dies für jedes Array tun, wirkt sich dies auf die Anwendungsleistung bis zu einem erheblichen Grad aus.

Je mehr Maschinenzyklus verwendet wird ==> Mehr Zeit für die Verarbeitung der Daten ==> Die Ausgabezeit wird erheblich verlängert . Damit kann Ihre Anwendungsdatenverarbeitung als niedrige Stufe betrachtet werden (bis zu einer gewissen Stufe verlangsamen).

Jugal Thakkar
quelle
17

Sie können die Schleife speichern, die Initialisierung erfolgt bereits auf 0. Auch für eine lokale Variable.

Bitte korrigieren Sie die Stelle, an der Sie die Klammern platzieren, zur besseren Lesbarkeit (anerkannte Best Practice):

int[] arr = new int[10];
KLE
quelle
14

Wenn Sie Float oder Integer verwenden, können Sie einen Standardwert wie diesen zuweisen ...

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

Sie können ein neues leeres Array mit Ihrer vorhandenen Arraygröße erstellen und es Ihrem Array zurückweisen. Dies kann schneller als andere sein. 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);
    }
}
}

Ergebnis:

0
0
0
0
0    
0
0
0
0
Kavishankar Karunakaran
quelle
1

Ja, int-Werte in einem Array werden auf Null initialisiert. Dies ist Ihnen jedoch nicht garantiert. In der Oracle-Dokumentation heißt es, dass dies eine schlechte Codierungspraxis ist.

nate
quelle
Gemäß der Java-Sprachspezifikation, Abschnitt 15.10.2 , werden alle Elemente des Arrays auf den Standardwert für den Komponententyp des Arrays initialisiert, dh 0, wenn ein Array mit einer Array-Erstellungsausnahme erstellt wird, die keine Anfangswerte bereitstellt im Fall von char []. Dies ist eine Garantie; Ich wäre ziemlich überrascht, wenn Oracle es für eine schlechte Praxis halten würde, sich darauf zu verlassen.
Ian Robertson
1

Die int-Werte sind nach der Initialisierung bereits Null, wie alle erwähnt haben. Wenn Sie in einer Situation tatsächlich Array-Werte auf Null setzen müssen und diese optimieren möchten, verwenden Sie 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);

Dies wird memcpyin den meisten oder allen JRE-Implementierungen unter dem Deckmantel verwendet. Beachten Sie, dass die Verwendung einer solchen Statik auch bei mehreren Threads sicher ist, da im schlimmsten Fall die Neuzuweisung mehrerer Threads erfolgtzeros gleichzeitig zugewiesen werden, was nichts schadet.

Sie können auch verwenden, Arrays.fillwie einige andere erwähnt haben. Arrays.fill könnte gebrauchenmemcpy in einem Smart - JVM, aber es ist wahrscheinlich nur eine Java - Schleife und die Grenzen, was dazugehört zu überprüfen.

Benchmarking Ihrer Optimierungen natürlich.

NateS
quelle
1

Noch ein Ansatz mit Lambda über Java 8

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

In c / cpp gibt es keine Verknüpfung, um alle Arrays mit dem Index Null zu initialisieren. Beispiel:

  int arr[10] = {0};

In Java gibt es jedoch ein magisches Werkzeug namens Arrays.fill (), das alle Werte in einem Array mit der Ganzzahl Ihrer Wahl füllt. Beispiel:

  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
quelle
1

Die Initialisierung ist bei Null nicht erforderlich, da der Standardwert von int in Java Null ist. Für andere Werte als Null stehen java.util.Arrayseine Reihe von Optionen zur Verfügung. Die einfachste ist die Füllmethode.

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]

Wir können auch Arrays.setAll () verwenden, wenn wir den Wert auf Bedingungsbasis füllen möchten:

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
quelle
0

Deklarieren Sie das Array als Instanzvariable in der Klasse, dh aus jeder Methode heraus, und JVM gibt ihm 0 als Standardwert. Sie brauchen sich keine Sorgen mehr zu machen

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

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

Ubeyd
quelle