Jakikolwiek skrót do inicjalizacji wszystkich elementów tablicy do zera?

281

W C/C++Kiedyś robiłem

int arr[10] = {0};

... aby zainicjować wszystkie moje elementy tablicy na 0.

Czy istnieje podobny skrót w Javie?

Chcę uniknąć używania pętli, czy to możliwe?

int arr[] = new int[10];
for(int i = 0; i < arr.length; i++) {
    arr[i] = 0;
}
koniec gry
źródło
2
java.util.Arrays.fill () int [] arr = new int [10]; i int arr [10] = {0}; wszystkie używają wewnętrznych pętli.
Kevin Kostlan

Odpowiedzi:

574

Domyślna wartość 0 dla tablic typów całkowych jest gwarantowana przez specyfikację języka :

Każda zmienna grupa zmienna przykład lub element tablicy jest inicjowany na wartość domyślną , gdy jest tworzony (§15.9, §15.10) [...] Dla typu int, domyślna wartość jest równa zeru, to znaczy 0.  

Jeśli chcesz zainicjować tablicę jednowymiarową na inną wartość, możesz użyć java.util.Arrays.fill () (która oczywiście użyje pętli wewnętrznie).

Michael Borgwardt
źródło
@MichaelBorgwardt Była mi pomocna odpowiedź. Czy wiązałoby się to z takimi samymi kosztami jak w przypadku pętli for?
maytham-ɯɐɥʇʎɐɯ
@ maytham-ɯɐɥıλɐɯ: możesz spojrzeć na kod źródłowy, jest dostarczany z JDK. Jest dokładnie tak samo, metoda składa się wyłącznie z całkowicie normalnej, bezpośredniej pętli for.
Michael Borgwardt,
@MichaelBorgwardt Co z wartościami lokalnej dwuwymiarowej tablicy? Czy to należy do „komponentu tablicy”?
Rishi
Arrays.fillniekoniecznie używa pętli.
NateS
@NateS: czy możesz podać przykład implementacji Java, która tego nie robi?
Michael Borgwardt,
104

Podczas gdy pozostałe odpowiedzi są poprawne (int wartości tablicy są domyślnie inicjowane na 0), jeśli chcesz to zrobić jawnie (np. Jeśli chcesz, aby tablica była wypełniona wartością 42), możesz użyć metody fill () macierze klasy:

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

Lub jeśli jesteś fanem 1-liniowych, możesz skorzystać z Collections.nCopies()rutyny:

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

Dałby arr wartość:

[42, 42, 42]

(chociaż jest Integer, i nie int, jeśli potrzebujesz pierwotnego typu, możesz odroczyć się do procedury Apache CommonsArrayUtils.toPrimitive() :

int [] primarr = ArrayUtils.toPrimitive(arr);
Adam Parkin
źródło
9
Jednej wkładki są dobre, ale List<Integer>do Integer[]celu int[]? To trochę skomplikowane.
dhardy
2
@dardardy Pewnie, ale właśnie dlatego w odpowiedzi jest też wersja 2-liniowa (jeśli martwisz się czynnikiem „zawiłości”).
Adam Parkin
inicjowanie tablicy 2d Arrays.fillmetodą powoduje problem i występuje błąd.
AKS
39

W Java wszystkie elementy (pierwotne liczby całkowite byte short, int, long) są początkowo wartość 0 domyślnie. Możesz zapisać pętlę.

Arne Deutsch
źródło
2
Podejrzewam, że dotyczy to prymitywnych typów ?!
Olimpiu POP
1
Prymitywne typy Java, takie jak int, nie są inicjowane.
Mirko Ebert
8
@ tfb785: To źle. Jak stwierdzono powyżej przez Michaela Borgwardta: prymitywne typy liczb całkowitych (krótkie, int, długie) są inicjowane na 0.
Arne Deutsch
1
Tak, tablica prymitywów Java takich jak int [] jest inicjowana na 0. Nie, jeden typ prymitywów Java nie jest inicjowany na 0.
Mirko Ebert
3
Ok, mówiąc dokładniej: prymitywni członkowie klasy (statyczni czy nie) są inicjowani na 0. Zmienne lokalne nie są.
Arne Deutsch
23

Jak to zmniejsza wydajność twojej aplikacji ....? Czytaj dalej.

W specyfikacji języka Java domyślną / początkową wartość dowolnego obiektu można podać jako następujące.

Dla typu bajt The Domyślna wartość jest zerowa , to znaczy wartość (bajt) wynosi 0 .

Dla typu Short The Domyślna wartość jest zerowa , to znaczy wartość (krótka) wynosi 0 .

Dla typu int The Domyślna wartość jest zerowa , czyli 0 .

Dla typu długi The Domyślna wartość jest zerowa , czyli 0L .

Dla typu pływaka The Domyślna wartość jest dodatnia zerowy , czyli 0.0f .

Dla typu podwójnego The Domyślna wartość jest dodatnia zerowy , czyli 0.0d .

Dla typu char The Domyślna wartość jest zerowa charakter, czyli „ \ u0000 ”.

Dla typu boolean The Domyślną wartością jest false .

Dla wszystkich typów referencyjnych The Domyślna wartość jest zerowa .

Biorąc to wszystko pod uwagę, nie trzeba inicjalizować zerowymi wartościami elementów tablicy, ponieważ domyślnie wszystkie elementy tablicy mają wartość 0 dla tablicy int.

Ponieważ tablica jest obiektem kontenerowym, który przechowuje stałą liczbę wartości jednego typu. Teraz typ tablicy dla ciebie to int, więc weź pod uwagę, że domyślna wartość dla wszystkich elementów tablicy będzie automatycznie równa 0, ponieważ zawiera typ int .

Teraz uważa się tablicę do typu String , tak aby wszystkie elementy tablicy ma wartość domyślną jest zerowa .

Dlaczego tego nie zrobisz ......?

możesz przypisać wartość zerową za pomocą pętli, jak sugerujesz w swoim pytaniu.

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

Ale jeśli to zrobisz, spowoduje to bezużyteczną utratę cyklu maszyny. a jeśli użyjesz w swojej aplikacji, w której masz wiele tablic i robisz to dla każdej tablicy, wpłynie to na wydajność aplikacji do znacznego poziomu.

Więcej wykorzystania cyklu maszynowego ==> Więcej czasu na przetwarzanie danych ==> Czas wyjściowy znacznie się wydłuży . dzięki czemu przetwarzanie danych aplikacji można uznać za niski poziom (zwolnij do pewnego poziomu).

Jugal Thakkar
źródło
17

Możesz zapisać pętlę, inicjalizacja jest już ustawiona na 0. Nawet dla zmiennej lokalnej.

Ale proszę poprawić miejsce, w którym umieszcza się nawiasy, aby zapewnić czytelność (uznana najlepsza praktyka):

int[] arr = new int[10];
KLE
źródło
14

Jeśli używasz liczby zmiennoprzecinkowej lub liczby całkowitej, możesz przypisać wartość domyślną w ten sposób ...

Integer[] data = new Integer[20];
Arrays.fill(data,new Integer(0));
Pankaj Goyal
źródło
6

Możesz utworzyć nową pustą tablicę z istniejącym rozmiarem tablicy i przypisać je z powrotem do tablicy. To może być szybsze niż inne. 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);
    }
}
}

Wynik:

0
0
0
0
0    
0
0
0
0
Kavishankar Karunakaran
źródło
1

Tak, wartości int w tablicy są inicjowane na zero. Ale nie masz tego gwarancji. Dokumentacja Oracle stwierdza, że ​​jest to zła praktyka kodowania.

Nate
źródło
Zgodnie ze specyfikacją języka Java, sekcja 15.10.2 , jeśli tablica jest tworzona z wyjątkiem tworzenia tablic, który nie podaje wartości początkowych, wówczas wszystkie elementy tablicy są inicjowane do wartości domyślnej dla typu komponentu tablicy - tj. 0 w przypadku char []. To jest gwarancja; Byłbym bardzo zaskoczony, że Oracle uznał, że poleganie na tym jest złą praktyką.
Ian Robertson,
1

Wartości int są już zerowe po inicjalizacji, jak wszyscy wspominali. Jeśli masz sytuację, w której faktycznie musisz ustawić wartości tablicy na zero i chcesz to zoptymalizować, użyj 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);

To stosuje się memcpypod przykryciem w większości lub wszystkich implementacjach JRE. Zauważ, że użycie takiego statycznego jest bezpieczne nawet w przypadku wielu wątków, ponieważ najgorszym przypadkiem jest wielokrotne przeniesienie wielu wątków zerosjednocześnie, co niczego nie zaszkodzi.

Możesz także użyć, Arrays.filljak wspomnieli inni. Arrays.fill można użyć memcpyw inteligentnej maszynie JVM, ale prawdopodobnie jest to po prostu pętla Java i związane z tym sprawdzanie granic.

Oczywiście sprawdź swoje optymalizacje.

NateS
źródło
1

Jeszcze inne podejście z wykorzystaniem lambda powyżej java 8

 Arrays.stream(new Integer[nodelist.size()]).map(e -> 
 Integer.MAX_VALUE).toArray(Integer[]::new);
brahmananda Kar
źródło
1

W c / cpp nie ma skrótu do inicjowania wszystkich tablic za pomocą zerowego indeksu dolnego.

  int arr[10] = {0};

Ale w java istnieje magiczne narzędzie o nazwie Arrays.fill (), które wypełni wszystkie wartości w tablicy wybraną liczbą całkowitą. Np .:

  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
źródło
1

Inicjalizacja nie jest wymagana w przypadku zera, ponieważ domyślna wartość int w Javie wynosi zero. W przypadku wartości innych niż zero dostępnych java.util.Arraysjest wiele opcji, najprostszą jest metoda wypełnienia.

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]

Możemy również użyć Arrays.setAll (), jeśli chcemy wypełnić wartość na podstawie warunków:

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
źródło
0

zadeklaruj tablicę jako zmienną instancji w klasie, tj. z każdej metody, a JVM da jej 0 jako wartość domyślną. Nie musisz się już martwić

Dhruvam Gupta
źródło
-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();               
    }

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

Ubeyd
źródło