Будь-який ярлик для ініціалізації всіх елементів масиву до нуля?


281

У C/C++мене раніше

int arr[10] = {0};

... ініціалізувати всі мої елементи масиву до 0.

Чи є подібний ярлик на Java?

Я хочу уникати використання циклу, чи це можливо?

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]; і int arr [10] = {0}; всі використовують внутрішні петлі.
Кевін Костлан

Відповіді:


574

Значення за замовчуванням 0 для масивів інтегральних типів гарантується мовною специфікацією :

Кожна змінна категорія, змінна інстанція або компонент масиву ініціалізуються зі значенням за замовчуванням, коли воно створюється (§15.9, §15.10) [...] Для типу intзначення за замовчуванням дорівнює нулю, тобто 0.  

Якщо ви хочете ініціалізувати одновимірний масив до іншого значення, ви можете використовувати java.util.Arrays.fill () (який, звичайно, буде використовувати цикл всередині).


@MichaelBorgwardt була мені корисною відповіддю. Чи буде це мати однакові витрати на це порівняно з циклом?
майтхем-ɯɐɥʇʎɐɯ

@ maytham-ɯɐɥıλɐɯ: ви можете подивитися вихідний код, він поставляється з JDK. Абсолютно те саме, метод складається з нічого, крім цілком нормального, прямого для циклу.
Майкл Боргвардт

@MichaelBorgwardt Що з значеннями локального двовимірного масиву? Чи підпадає це під "компонент масиву?"
Ріші

Arrays.fillне обов'язково використовувати цикл.
NateS

@NateS: чи можете ви навести приклад реалізації Java, яка не відповідає?
Майкл Боргвардт

104

Хоча інші відповіді правильні (значення масиву int за замовчуванням ініціалізовано до 0), якщо ви хотіли це зробити явно (скажімо, наприклад, якщо ви хочете масив, заповнений значенням 42), ви можете використовувати метод fill () масиви клас:

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

Або якщо ви любитель 1-лайнерів, можете скористатися Collections.nCopies()рутиною:

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

Дасть arr значення:

[42, 42, 42]

(хоча це так Integer, і ні int, якщо вам потрібен примітивний тип, який ви можете відкласти до звичайної програми Apache CommonsArrayUtils.toPrimitive() :

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

9
Однокласники хороші, але List<Integer>до Integer[]чого int[]? Це трохи заплутано.
безтурботний

2
@dhardy Звичайно, але саме тому у відповіді є і дворядкова версія (якщо ви стурбовані фактором "згорнутого").
Адам Паркін

ініціалізація масиву 2d Arrays.fillметодом створює проблему і виникає помилка.
AKS

39

У Java всі елементи (примітивні цілочисельні типи byte short, int, long) започатковано 0 за замовчуванням. Можна зберегти цикл.


2
Я припускаю, що це стосується примітивних типів ?!
Olimpiu POP

1
Примітивні типи Java, як-от int, не ініціалізуються.
Мірко Еберт

8
@ tfb785: Це неправильно. Як зазначав Майкл Боргвардт: примітивні цілочисельні типи (короткі, int, довгі) ініціалізуються до 0.
Arne Deutsch

1
Так, масив Java примітивів, таких як int [], ініціюється з 0. Ні, один примітивний тип java не ініціюється з 0.
Mirko Ebert

3
Гаразд, якщо бути точним: примітивні члени класу (статичні вони чи ні) ініціалізуються з 0. Локальні змінні - ні.
Arne Deutsch

23

Як це знижує продуктивність вашої програми ....? Читайте далі.

У специфікації мови Java за замовчуванням / початковим значенням для будь-якого об'єкта може бути надано наступне.

Для байтів типу значення за замовчуванням дорівнює нулю , тобто значення (байт) дорівнює 0 .

Для типу short , значення за замовчуванням дорівнює нулю , тобто значення (short) дорівнює 0 .

Для типу int значення за замовчуванням дорівнює нулю , тобто 0 .

Для типу long , значення за замовчуванням дорівнює нулю , тобто 0L .

Для float типу значення за замовчуванням - додатний нуль , тобто 0,0f .

Для типу double - значення за замовчуванням - це додатний нуль , тобто 0,0d .

Для типу CHAR , то значення по замовчуванням є нульовим символом, тобто « \ u0000 ».

Для типу boolean значення за замовчуванням - false .

Для всіх типів посилань значення за замовчуванням є нульовим .

Враховуючи все це, вам не потрібно ініціалізувати з нульовими значеннями для елементів масиву, оскільки за замовчуванням всі елементи масиву 0 для масиву int.

Оскільки масив - це контейнерний об'єкт, який містить фіксовану кількість значень одного типу. Тепер Тип масиву для вас є int, тому врахуйте, що значення за замовчуванням для всіх елементів масиву буде автоматично 0 Оскільки він містить тип int .

Тепер розглянемо в масив для строкового типу , так що всі елементи масиву має значення по замовчуванням є нульовим .

Чому б цього не зробити ......?

ви можете призначити нульове значення, використовуючи цикл, як ви пропонуєте у своєму запитанні.

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

Але якщо ви зробите це, то це буде марною втратою машинного циклу. і якщо ви використовуєте у своїй програмі, де у вас є багато масивів, і ви робите це для кожного масиву, це вплине на продуктивність програми до значного рівня.

Чим більше використовувати машинний цикл ==> Більше часу для обробки даних ==> Час виводу значно збільшиться . так що обробка даних вашої програми може розглядатися як низький рівень (повільний до деякого рівня).


17

Ви можете зберегти цикл, ініціалізація вже зроблена до 0. Навіть для локальної змінної.

Але, будь ласка, виправте місце, де ви розміщуєте дужки, на предмет читабельності (визнана найкраща практика):

int[] arr = new int[10];

14

Якщо ви використовуєте Float або Integer, ви можете призначити значення за замовчуванням, як це ...

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

6

Ви можете створити новий порожній масив із наявним розміром масиву, і ви можете призначити їх своєму масиву. Це може швидше, ніж інші. Знімок:

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

Результат:

0
0
0
0
0    
0
0
0
0

1

Так, значення int у масиві ініціалізуються до нуля. Але вам цього не гарантують. У документації Oracle зазначається, що це погана практика кодування.


Відповідно до специфікації мови Java, розділ 15.10.2 , якщо масив створюється з виключенням для створення масиву, який не забезпечує початкових значень, то всі елементи масиву ініціалізуються до значення за замовчуванням для типу компонента масиву - тобто 0 у випадку char []. Це гарантія; Я був би дуже здивований, що Oracle вважав покладатися на нього поганою практикою.
Ян Робертсон

1

Значення int вже нульові після ініціалізації, як уже згадували всі. Якщо у вас є ситуація, коли вам потрібно встановити значення масиву на нуль і хочете оптимізувати це, скористайтеся 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);

Це використовується memcpyпід обкладинками у більшості або всіх реалізаціях JRE. Зауважте, що використання такої статики є безпечною навіть для декількох потоків, оскільки найгірший випадок - це перерозподіл декількох потоківzeros одночасно, що нічого не шкодить.

Ви також можете використовувати, Arrays.fillяк згадували деякі інші. Arrays.fill може використовуватись memcpyу розумному JVM, але це, ймовірно, лише цикл Java та перевірка меж, що це тягне за собою.

Звичайно, порівняйте свої оптимізації.


1

Ще один підхід, використовуючи лямбда вище java 8

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

1

У c / cpp немає ярлика, але ініціалізувати всі масиви з нульовим індексом.

  int arr[10] = {0};

Але в Java є магічний інструмент під назвою Arrays.fill (), який заповнить усі значення масиву цілим числом на ваш вибір.

  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

Ініціалізація не потрібна у випадку нуля, оскільки значення за замовчуванням int в Java дорівнює нулю. Для значень, відмінних від нуля, java.util.Arraysпередбачено ряд варіантів, найпростішим є метод заповнення.

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]

Ми також можемо використовувати Arrays.setAll (), якщо хочемо заповнити значення за умови:

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

оголосити масив змінною екземпляра в класі, тобто з кожного методу, і JVM дасть йому 0 як значення за замовчуванням. Вам більше не потрібно хвилюватися


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

результат 0123456 -1012345 -2-101234 -3-2-10123 -4-3-2-1012 -5-4-3-2-101 -6-5-4-3-2-10

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.