Bất kỳ phím tắt để khởi tạo tất cả các phần tử mảng bằng không?


281

Trong C/C++tôi đã từng làm

int arr[10] = {0};

... để khởi tạo tất cả các phần tử mảng của tôi thành 0.

Có một phím tắt tương tự trong Java?

Tôi muốn tránh sử dụng các vòng lặp, nó có thể?

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

2
java.util.Arrays.fill () int [] Array = new int [10]; và int mảng [10] = {0}; Tất cả sử dụng các vòng lặp nội bộ.
Kevin Kostlan

Câu trả lời:


574

Giá trị mặc định là 0 cho các mảng kiểu tích phân được đảm bảo bởi thông số ngôn ngữ :

Mỗi biến lớp, biến thể hiện hoặc thành phần mảng được khởi tạo với một giá trị mặc định khi nó được tạo (§15.9, §15.10) [...] Đối với loại int, giá trị mặc định là 0, nghĩa là , 0.  

Nếu bạn muốn khởi tạo một mảng một chiều thành một giá trị khác, bạn có thể sử dụng java.util.Arrays.fill () (tất nhiên sẽ sử dụng một vòng lặp bên trong).


@MichaelBorgwardt là câu trả lời hữu ích cho tôi. Điều đó có cùng chi phí để làm điều đó so với vòng lặp không?
maytham-

@ maytham-ɯɐɥıλɐɯ: bạn có thể xem mã nguồn, nó đi kèm với JDK. Nó hoàn toàn giống nhau, phương thức này không có gì ngoài một vòng lặp hoàn toàn bình thường, đơn giản cho vòng lặp.
Michael Borgwardt

@MichaelBorgwardt Còn các giá trị của mảng 2 chiều cục bộ thì sao? Điều đó có thuộc "thành phần mảng?"
Rishi

Arrays.fillkhông nhất thiết phải sử dụng một vòng lặp.
NateS

@NateS: bạn có thể đưa ra một ví dụ về việc triển khai Java không?
Michael Borgwardt

104

Mặc dù các câu trả lời khác là đúng (giá trị mảng int theo mặc định được khởi tạo thành 0), nếu bạn muốn làm rõ ràng như vậy (ví dụ nếu bạn muốn một mảng chứa đầy giá trị 42), bạn có thể sử dụng phương thức fill () của các Mảng lớp:

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

Hoặc nếu bạn là người hâm mộ của 1 lớp lót, bạn có thể sử dụng Collections.nCopies()thói quen:

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

Sẽ cung cấp cho mảng giá trị:

[42, 42, 42]

(mặc dù vậy Integer, và không int, nếu bạn cần kiểu nguyên thủy, bạn có thể trì hoãn thói quen Apache CommonsArrayUtils.toPrimitive() :

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

9
One-lót là tốt, nhưng List<Integer>để Integer[]đến int[]? Đó là một chút phức tạp.
dhardy

2
@dhardy Chắc chắn, nhưng đó là lý do tại sao cũng có phiên bản 2 dòng trong câu trả lời (nếu bạn quan tâm đến yếu tố "phức tạp").
Adam Parkin

khởi tạo mảng 2d với Arrays.fillphương thức đang tạo ra vấn đề và xảy ra lỗi.
AKS

39

Trong java tất cả các yếu tố (loại số nguyên nguyên thủy byte short, int, long) được khởi tạo 0 theo mặc định. Bạn có thể lưu vòng lặp.


2
Tôi cho rằng điều này giữ cho các loại nguyên thủy?!
Olimpiu POP

1
Các kiểu java nguyên thủy, như int, không được khởi tạo.
Mirko Ebert

8
@ tfb785: Điều này sai. Như đã nêu ở trên bởi Michael Borgwardt: các loại số nguyên nguyên (ngắn, int, dài) được khởi tạo thành 0.
Arne Deutsch

1
Có, mảng nguyên thủy java như int [] được khởi tạo bằng 0. Không, một kiểu nguyên thủy java không được bắt đầu bằng 0.
Mirko Ebert

3
Ok, chính xác là: các thành viên lớp nguyên thủy (có thể là tĩnh hay không) được khởi tạo với 0. Biến cục bộ thì không.
Arne Đức

23

Làm thế nào nó làm giảm hiệu suất của ứng dụng của bạn ....? Đọc sau.

Trong Đặc tả ngôn ngữ Java, Giá trị mặc định / ban đầu cho bất kỳ Đối tượng nào có thể được cung cấp dưới dạng Theo sau.

Đối với kiểu byte , giá trị mặc định0 , nghĩa là giá trị của (byte) là 0 .

Đối với loại ngắn , giá trị mặc định0 , nghĩa là giá trị của (ngắn) là 0 .

Đối với kiểu int , giá trị mặc định0 , nghĩa là 0 .

Đối với loại dài , giá trị mặc định0 , nghĩa là 0L .

Đối với kiểu float , giá trị mặc định0 dương , nghĩa là 0,0f .

Đối với loại double , giá trị mặc định0 dương , nghĩa là 0,0d .

Đối với kiểu char , giá trị mặc định là ký tự null , nghĩa là ' \ u0000 '.

Đối với kiểu boolean , giá trị mặc địnhsai .

Đối với tất cả các loại tham chiếu , giá trị mặc địnhnull .

Bằng cách xem xét tất cả điều này, bạn không cần phải khởi tạo với giá trị 0 cho các phần tử mảng vì theo mặc định, tất cả các phần tử mảng là 0 cho mảng int.

Bởi vì Mảng là một đối tượng chứa một số giá trị cố định của một loại. Bây giờ Loại mảng cho bạn là int vì vậy hãy xem xét giá trị mặc định cho tất cả các thành phần mảng sẽ tự động 0 Vì nó đang giữ kiểu int .

Bây giờ xem xét các mảng cho loại Chuỗi sao cho tất cả các phần tử mảng có giá trị mặc địnhrỗng .

Tại sao không làm điều đó ......?

bạn có thể gán giá trị null bằng cách sử dụng vòng lặp như bạn đề xuất trong Câu hỏi của mình.

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

Nhưng nếu bạn làm như vậy thì nó sẽ làm mất chu kỳ máy vô dụng. và nếu bạn sử dụng trong ứng dụng của mình, nơi bạn có nhiều mảng và bạn làm điều đó cho từng mảng thì nó sẽ ảnh hưởng đến Hiệu suất Ứng dụng lên đến mức đáng kể.

Việc sử dụng càng nhiều chu kỳ máy ==> Nhiều thời gian hơn để xử lý dữ liệu ==> Thời gian đầu ra sẽ tăng đáng kể . để việc xử lý dữ liệu ứng dụng của bạn có thể được coi là mức thấp (Làm chậm đến một mức nào đó).


17

Bạn có thể lưu vòng lặp, việc khởi tạo đã được thực hiện thành 0. Ngay cả đối với một biến cục bộ.

Nhưng vui lòng sửa lại vị trí nơi bạn đặt dấu ngoặc, để dễ đọc (thực hành tốt nhất được công nhận):

int[] arr = new int[10];

14

Nếu bạn đang sử dụng Float hoặc Integer thì bạn có thể gán giá trị mặc định như thế này ...

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

6

Bạn có thể tạo một mảng trống mới với kích thước mảng hiện có của mình và bạn có thể gán lại chúng cho mảng của mình. Điều này có thể nhanh hơn khác. Bắn tỉa:

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

Kết quả :

0
0
0
0
0    
0
0
0
0

1

Có, giá trị int trong một mảng được khởi tạo bằng không. Nhưng bạn không được đảm bảo điều này. Tài liệu của Oracle nói rằng đây là một thực hành mã hóa xấu.


Theo đặc tả ngôn ngữ Java, phần 15.10.2 , nếu một mảng được tạo với ngoại lệ tạo mảng không cung cấp các giá trị ban đầu, thì tất cả các thành phần của mảng được khởi tạo thành giá trị mặc định cho loại thành phần của mảng - tức là 0 trong trường hợp char []. Đây là một sự đảm bảo; Tôi khá ngạc nhiên khi Oracle coi việc dựa vào nó là một thực tiễn tồi.
Ian Robertson

1

Các giá trị int đã bằng 0 sau khi khởi tạo, như mọi người đã đề cập. Nếu bạn có một tình huống mà bạn thực sự cần phải đặt giá trị mảng thành 0 và muốn tối ưu hóa điều đó, hãy sử dụng 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);

Điều này sử dụng memcpydưới vỏ bọc trong hầu hết hoặc tất cả các triển khai JRE. Lưu ý rằng việc sử dụng tĩnh như thế này là an toàn ngay cả với nhiều luồng, vì trường hợp xấu nhất là nhiều luồng được phân bổ lại zerosđồng thời, điều này không làm tổn hại gì.

Bạn cũng có thể sử dụng Arrays.fillnhư một số người khác đã đề cập. Arrays.fill có thể sử dụng memcpytrong một JVM thông minh, nhưng có lẽ chỉ là một vòng lặp Java và các giới hạn kiểm tra đòi hỏi phải có.

Điểm chuẩn tối ưu hóa của bạn, tất nhiên.


1

Một cách tiếp cận khác bằng cách sử dụng lambda trên java 8

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

1

Trong c / cpp không có phím tắt nào ngoài việc khởi tạo tất cả các mảng với chỉ mục bằng 0.Ex:

  int arr[10] = {0};

Nhưng trong java có một công cụ ma thuật gọi là Arrays.fill () sẽ điền vào tất cả các giá trị trong một mảng với số nguyên bạn chọn .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

Không yêu cầu khởi tạo trong trường hợp bằng 0 vì giá trị mặc định của int trong Java bằng không. Đối với các giá trị khác 0 java.util.Arrayscung cấp một số tùy chọn, đơn giản nhất là phương thức điền.

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]

Chúng tôi cũng có thể sử dụng Arrays.set ALL () nếu chúng tôi muốn điền giá trị trên cơ sở điều kiện:

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

khai báo mảng dưới dạng biến đối tượng trong lớp tức là ngoài mọi phương thức và JVM sẽ cho nó 0 làm giá trị mặc định. Bạn không cần phải lo lắng nữa


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

kết quả 0123456 -1012345 -2-101234 -3-2-10123 -4-3-2-1012 -5-4-3-2-101 -6-5-4-3-2-10

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.