将所有数组元素初始化为零的快捷方式吗?


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}; 都使用内部循环。
凯文·科斯特兰

Answers:


574

语言规范保证整数类型数组的默认值为0 :

每个类变量,实例变量或数组组件在创建时都会用默认值初始化(第15.9节,第15.10节)。对于type int,默认值为零,即0。  

如果要将一维数组初始化为其他值,则可以使用java.util.Arrays.fill()(当然,它会在内部使用循环)。


@MichaelBorgwardt对我很有帮助。与for循环相比,这样做的成本是否相同?
maytham-ɯɐɥʇʎɐɯ

@maytham-ɯɐɥıλɐɯ:您可以查看源代码,它是JDK附带的。完全一样,该方法只包含一个完全正常,直接的for循环。
Michael Borgwardt

@MichaelBorgwardt本地二维数组的值如何?那属于“数组组件”吗?
Rishi

Arrays.fill不一定要使用循环。
NateS

@NateS:能否举一个没有Java实现的示例?
Michael Borgwardt

104

尽管其他答案是正确的(int数组值默认情况下初始化为0),但是如果您想显式地这样做(例如,如果您想要用值42填充数组),则可以使用以下方法的fill()方法:该数组类:

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

或者,如果您是1-liners的粉丝,则可以使用以下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[]?这有点令人费解。
dhardy 2013年

2
@dhardy当然可以,但这就是为什么答案中也有2行版本的原因(如果您担心“复杂”的因素)。
亚当·帕金

Arrays.fill方法初始化2d数组会造成问题,并且会发生错误。
AKS

39

Java中的所有元素(原始整数类型byte shortintlong)由缺省初始化为0。您可以保存循环。


2
我想这适用于原始类型吗?
Olimpiu POP,

1
原始Java类型(例如int)不会被初始化。
Mirko Ebert

8
@ tfb785:这是错误的。如上所述通过迈克尔博格瓦特表示:原始整数类型(短整型,整型,长)被初始化为0。
阿恩德语

1
是的,Java原始象int []数组与0没有启动,一个Java原始类型不为0启动
的Mirko埃伯特

3
好的,确切地说:基本类成员(无论是静态的还是非静态的)都以0初始化。局部变量不是。
Arne Deutsch 2014年

23

它如何降低应用程序的性能...?阅读以下内容。

在Java语言规范中,任何对象的默认值/初始值都可以指定为Follows。

对于类型字节,所述默认值,即,(字节)的值是0

对于类型,所述默认值,即,(短)的值是0

对于类型INT,所述默认值,即,0

对于类型时,默认值,也就是0L

对于类型浮子,该默认值正零,即,0.0F

对于类型,则默认值正零,也就是0.0D

对于类型字符,则默认值字符,也就是“ \ u0000的 ”。

对于类型布尔型,则默认值假的

对于所有引用类型默认值

通过考虑所有这些,您不需要为数组元素初始化零值,因为默认情况下,对于int数组,所有数组元素均为0。

因为数组是一个包含固定数量的单一类型值的容器对象。现在,您的数组类型为int,因此请考虑所有数组元素的默认值将自动为0,因为它持有int type

现在考虑阵列字符串类型,使所有的数组元素具有默认值

为什么不这样做……?

您可以按照问题中的建议使用循环来分配空值。

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 []。这是保证;我对甲骨文认为依靠它是一种不好的做法感到非常惊讶。
伊恩·罗伯逊

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之上使用lambda的另一种方法

 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

如果为零,则不需要初始化,因为Java中int的默认值为零。对于非零值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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.