Любой ярлык для инициализации всех элементов массива в ноль?


282

В 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 Был полезным ответом для меня. Будет ли это иметь такую ​​же стоимость по сравнению с циклом for?
Maytham-ɯɐɥʇʎɐɯ

@ maytham-ɯɐɥıλɐɯ: вы можете посмотреть исходный код, он поставляется с JDK. Это то же самое, метод состоит только из совершенно нормального, простого цикла.
Майкл Боргвардт

@MichaelBorgwardt А как насчет значений локального 2-мерного массива? Это подпадает под "компонент массива?"
Риши

Arrays.fillне обязательно использовать цикл.
NateS

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

105

Хотя остальные ответы верны (значения массива 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: Это неправильно. Как указывалось выше Майклом Боргвардтом: примитивные целочисленные типы (short, int, long) инициализируются равными 0.
Arne Deutsch

1
Да, массив java-примитивов, таких как int [], инициируется с 0. Нет, один тип java-примитивов не инициируется с 0.
Мирко Эберт

3
Хорошо, чтобы быть точным: примитивные члены класса (будь то статические или нет) инициализируются с 0. Локальные переменные - нет.
Арне Дойч

23

Как это снижает производительность вашего приложения ....? Читайте следующее.

В спецификации языка Java значение по умолчанию / начальное значение для любого объекта может быть задано следующим образом.

Для типа байта , то значение по умолчанию является нулевым , то есть, значение (байт) 0 .

Для типа короткого замыкания , то значение по умолчанию является нулевым , то есть, значение (короткий) является 0 .

Для типа Int , то значение по умолчанию является ноль , то есть 0 .

Для типа долго , то значение по умолчанию является ноль , то есть 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

Вы можете создать новый пустой массив с вашим существующим размером массива, и вы можете назначить их обратно вашему массиву. Это может быстрее, чем другие. 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);
    }
}
}

Результат:

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.