ทางลัดใด ๆ ในการเริ่มต้นองค์ประกอบอาร์เรย์ทั้งหมดให้เป็นศูนย์?


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}; ใช้ลูปภายในทั้งหมด
Kevin Kostlan

คำตอบ:


574

ค่าเริ่มต้นของ 0 สำหรับอาร์เรย์ของชนิดที่ครบถ้วนจะถูกรับประกันโดยข้อมูลจำเพาะภาษา :

ตัวแปรระดับแต่ละตัวแปรเช่นหรือองค์ประกอบอาร์เรย์จะเริ่มต้นด้วยค่าเริ่มต้นเมื่อมันถูกสร้างขึ้น (§15.9, §15.10) [ ... ] สำหรับประเภทintค่าเริ่มต้นเป็นศูนย์, 0ที่อยู่,  

หากคุณต้องการเริ่มต้นอาร์เรย์หนึ่งมิติเป็นค่าอื่นคุณสามารถใช้java.util.Arrays.fill () (ซึ่งแน่นอนว่าจะใช้ลูปภายใน)


@MichaelBorgwardt เป็นคำตอบที่เป็นประโยชน์สำหรับฉัน จะมีค่าใช้จ่ายเท่ากันเมื่อเทียบกับการวนซ้ำหรือไม่
maytham-ɯɐɥʇʎɐɯ

@ maytham-ɯɐɥıλɐɯ: คุณสามารถดูซอร์สโค้ดมันมาพร้อมกับ JDK มันเหมือนกันทุกอย่างวิธีการประกอบด้วยอะไร แต่ปกติอย่างสมบูรณ์แบบตรงไปตรงมาสำหรับวง
Michael Borgwardt

@MichaelBorgwardt แล้วค่าของอาร์เรย์ 2 มิติในพื้นที่เป็นอย่างไร สิ่งนี้อยู่ภายใต้ "องค์ประกอบของอาร์เรย์หรือไม่"
Rishi

Arrays.fillไม่จำเป็นต้องใช้การวนซ้ำ
NateS

@NateS: คุณสามารถยกตัวอย่างของการใช้งานจาวาที่ไม่?
Michael Borgwardt

104

ในขณะที่คำตอบอื่น ๆ นั้นถูกต้อง (ค่าเริ่มต้น int คือค่าเริ่มต้นที่ 0) หากคุณต้องการทำอย่างชัดเจน (เช่นถ้าคุณต้องการอาร์เรย์ที่เต็มไปด้วยค่า 42) คุณสามารถใช้วิธีการเติม () อาร์เรย์ระดับ:

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 Commons ได้ArrayUtils.toPrimitive() :

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

9
หนึ่งสมุทรเป็นสิ่งที่ดี แต่List<Integer>จะInteger[]ไปint[]? มันค่อนข้างซับซ้อน
dhardy

2
@hardy แน่นอน แต่นั่นเป็นสาเหตุที่มีคำตอบเวอร์ชัน 2 บรรทัดอยู่ด้วย (ถ้าคุณกังวลเกี่ยวกับปัจจัย "ที่ซับซ้อน")
Adam Parkin

เริ่มต้นอาร์เรย์ 2d ด้วยArrays.fillวิธีการคือการสร้างปัญหาและข้อผิดพลาดเกิดขึ้น
AKS

39

ใน java องค์ประกอบทั้งหมด (ประเภทจำนวนเต็มดั้งเดิมbyte short, int, long) จะเริ่มต้นใช้ให้เป็น 0 โดยค่าเริ่มต้น คุณสามารถบันทึกลูป


2
ฉันคิดว่านี่ถือสำหรับประเภทดั้งเดิม?!
Olimpiu POP

1
ประเภทจาวาดั้งเดิม, เช่น int, ไม่ได้เริ่มต้น
Mirko Ebert

8
@ tfb785: นี่มันผิด ตามที่ระบุไว้ข้างต้นโดย Michael Borgwardt: ประเภทจำนวนเต็มดั้งเดิม (สั้น, int, long) จะเริ่มต้นเป็น 0
Arne Deutsch

1
ใช่อาเรย์ดั้งเดิมของจาวาเช่น int [] นั้นเริ่มต้นด้วย 0 ไม่ชนิดจาวาดั้งเดิมไม่ได้เริ่มด้วย 0
Mirko Ebert

3
ตกลงเพื่อความแม่นยำ: สมาชิกชั้นเรียนดั้งเดิม (ไม่ว่าจะเป็นแบบคงที่หรือไม่) จะเริ่มต้นด้วย 0 ตัวแปรท้องถิ่นไม่ได้
Arne Deutsch

23

มันช่วยลดประสิทธิภาพของแอปพลิเคชันของคุณได้อย่างไร .... ? อ่านต่อไปนี้

ในข้อกำหนดภาษา Java ค่าเริ่มต้น / ค่าเริ่มต้นสำหรับวัตถุใด ๆ ที่สามารถได้รับดังต่อไปนี้

สำหรับประเภทไบต์ที่ค่าเริ่มต้นเป็นศูนย์นั่นคือค่าของ (ไบต์) เป็น0

สำหรับประเภทระยะสั้นที่ค่าเริ่มต้นเป็นศูนย์นั่นคือค่าของ (สั้น) เป็น0

สำหรับประเภทintที่ค่าเริ่มต้นเป็นศูนย์ , ที่อยู่, 0

สำหรับประเภทยาวที่ค่าเริ่มต้นเป็นศูนย์ , ที่อยู่, 0L

สำหรับประเภทลอยที่ค่าเริ่มต้นเป็นศูนย์บวก , ที่อยู่, 0.0f

สำหรับประเภทคู่ที่ค่าเริ่มต้นเป็นศูนย์บวก , ที่อยู่, 0.0d

สำหรับประเภทถ่านที่ค่าเริ่มต้นเป็นnullตัวละครที่เป็น ' \ u0000 '

สำหรับประเภทบูลที่ค่าเริ่มต้นเป็นเท็จ

สำหรับทุกประเภทการอ้างอิงที่ค่าเริ่มต้นเป็นโมฆะ

โดยการพิจารณาทั้งหมดนี้คุณไม่จำเป็นต้องเริ่มต้นด้วยค่าศูนย์สำหรับองค์ประกอบอาร์เรย์เพราะโดยค่าเริ่มต้นองค์ประกอบอาร์เรย์ทั้งหมดเป็น 0 สำหรับ int array

เนื่องจากอาเรย์เป็นวัตถุคอนเทนเนอร์ที่เก็บค่าคงที่ประเภทเดียว ตอนนี้ประเภทของอาร์เรย์สำหรับคุณคือintดังนั้นจึงควรพิจารณาค่าเริ่มต้นสำหรับองค์ประกอบมากมายทั้งหมดจะเป็นโดยอัตโนมัติ 0เพราะมันเป็นโฮลดิ้งชนิด int

ตอนนี้พิจารณาอาร์เรย์สำหรับชนิดสตริงเพื่อให้องค์ประกอบมากมายทั้งหมดมีค่าเริ่มต้นเป็นโมฆะ

ทำไมไม่ทำอย่างนั้น ......

คุณสามารถกำหนดค่า Null โดยใช้การวนซ้ำตามที่คุณแนะนำในคำถามของคุณ

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 ระบุว่านี่เป็นวิธีการเข้ารหัสที่ไม่ดี


ตามข้อกำหนดภาษาจาวาส่วนที่15.10.2ถ้าอาเรย์ถูกสร้างขึ้นด้วยข้อยกเว้นการสร้างอาเรย์ที่ไม่ได้ให้ค่าเริ่มต้นองค์ประกอบทั้งหมดของอาเรย์จะเริ่มต้นเป็นค่าเริ่มต้นสำหรับประเภทองค์ประกอบของอาเรย์ - เช่น 0 ในกรณีของถ่าน [] นี่คือการรับประกัน; ฉันค่อนข้างประหลาดใจที่ Oracle คิดว่าการใช้มันเป็นการปฏิบัติที่ไม่ดี
Ian Robertson

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

วิธีการอื่นโดยใช้แลมบ์ดาเหนือจาวา 8

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

1

ใน c / cpp ไม่มีทางลัด แต่การเริ่มต้นอาร์เรย์ทั้งหมดด้วยตัวห้อยเป็นศูนย์ Ex:

  int arr[10] = {0};

แต่ใน java มีเครื่องมือวิเศษที่เรียกว่า Arrays.fill () ซึ่งจะเติมค่าทั้งหมดในอาร์เรย์ด้วยจำนวนเต็มที่คุณเลือก Ex:

  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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.