Mảng trong java có độ dài cố định. Tại sao Java lại cho phép các mảng có kích thước 0?
String[] strings = new String[0];
Câu trả lời:
Nó có nghĩa là nó trống rỗng. Tức là bạn có thể lặp lại nó như thể nó có các mục và không có kết quả nào xảy ra:
for(int k = 0; k < strings.length; k++){
// something
}
Qua đó tránh được việc phải kiểm tra. Nếu mảng được đề cập null
, một ngoại lệ sẽ xảy ra, nhưng trong trường hợp này, nó không làm gì cả, điều này có thể phù hợp.
Tại sao Java cho phép các mảng có kích thước 1? Không phải là khá vô ích khi bao bọc một giá trị trong một mảng? Sẽ không đủ nếu Java chỉ cho phép các mảng có kích thước 2 hoặc lớn hơn?
Vâng, chúng tôi có thể vượt qua null
thay vì một mảng trống và một đối tượng hoặc nguyên thủy thay vì một ma trận kích thước một.
Nhưng có một số lập luận tốt chống lại một hạn chế như vậy. Đối số hàng đầu của cá nhân tôi:
Hạn chế quá phức tạp và không thực sự cần thiết
Để giới hạn mảng ở kích thước [1..INTEGER.MAX_INT], chúng tôi sẽ phải thêm nhiều kiểm tra boudary bổ sung, (đồng ý với nhận xét của Konrads) logic chuyển đổi và quá tải phương thức đối với mã của chúng tôi. Loại trừ 0 (và có thể là 1) khỏi kích thước mảng cho phép không tiết kiệm chi phí, nó đòi hỏi nỗ lực bổ sung và có tác động tiêu cực đến hiệu suất.
Mô hình mảng vector
Một mảng là một mô hình dữ liệu tốt cho một vector (toán học, không những Vector
lớp!). Và tất nhiên, một vectơ trong toán học có thể là không chiều. Đó là khái niệm khác với không tồn tại.
Sidenote - một trình bao bọc nổi bật cho mảng (char-) là String
lớp. Immutable hiện String
thực hóa khái niệm về một mảng trống: nó là String ( ""
) rỗng .
>= 0
thành > 0
). Nhưng tất nhiên bạn đã đúng về phần còn lại nên việc thêm phần hạn chế này sẽ không có ý nghĩa.
Đôi khi trả về mảng kích thước bằng 0 sẽ thân thiện hơn nhiều so với giá trị null.
Hãy xem xét điều này (giải thích chi tiết hơn về câu trả lời của Noon):
public String[] getStrings() {
if( foo ) {
return null;
} else {
return new String[] {"bar, "baz"};
}
}
String[] strings = getStrings();
if (strings != null) {
for (String s : strings) {
blah(s);
}
}
Bây giờ hãy so sánh nó với cái này:
public String[] getStrings() {
if( foo ) {
return new String[0];
} else {
return new String[] {"bar, "baz"};
}
}
// the if block is not necessary anymore
String[] strings = getStrings();
for (String s : strings) {
blah(s);
}
Điều này (trả về mảng trống chứ không phải giá trị rỗng), trên thực tế là một phương pháp hay nhất trong thế giới thiết kế API Java.
Bên cạnh đó, trong Java, bạn có thể ẩn Danh sách (ví dụ: ArrayList) thành các mảng và việc chuyển đổi một danh sách trống thành một mảng trống chỉ có ý nghĩa.
Giống như C ++, nó cho phép xử lý sạch hơn khi không có dữ liệu.
Một trường hợp khác mà mảng có độ dài bằng 0 có thể hữu ích: Để trả về một mảng chứa tất cả các phần tử trong danh sách:
<T> T[ ] toArray(T[ ] a)
Một mảng có độ dài bằng 0 có thể được sử dụng để truyền kiểu của mảng vào phương thức này. Ví dụ:
ClassA[ ] result = list.toArray(new ClassA[0]);
Mảng có độ dài bằng không vẫn là một thể hiện của Đối tượng chứa không phần tử.
Một trường hợp mà tôi có thể nghĩ đến khi một mảng trống cực kỳ hữu ích là sử dụng nó thay vì null trong trường hợp không cho phép null. Một ví dụ có thể về điều đó là BlockingQueue của mảng. Khi bạn muốn báo hiệu kết thúc đầu vào cho phía đọc, bạn sẽ làm gì? Gửi null có vẻ như là một lựa chọn hiển nhiên, nhưng vấn đề là BlockingQueue không chấp nhận null. Bạn có thể bao bọc mảng của mình bên trong một lớp với boolean last;
loại trường "", nhưng đó là loại trường quá mức cần thiết. Gửi một mảng trống (có kích thước bằng 0) có vẻ là lựa chọn hợp lý nhất.
Một trường hợp khác khi mảng có độ dài bằng 0 rất hữu ích là khi sao chép một mảng hai chiều. Tôi có thể viết:
public int[][] copyArray(int[][] array){
int[][] newArray = new int[array.length][0];
for(int i=0;i<array.length;i++){
newArray[i] = array[i];
}
return newArray;
Do mọi tham chiếu mảng trong mảng đang bị ghi đè, nên việc khởi tạo chúng dưới dạng các mảng có độ dài bằng không là hiệu quả nhất.
Độ dài 0 byte[]
hoặc char[]
có thể biểu thị giá trị trống String
, khác với null
. Lấy các byte hoặc ký tự dưới dạng mảng từ chuỗi (sử dụng getBytes()
, getChars()
thuộc String
lớp, v.v.) và ngược lại khi tạo thành String
từ s byte[]
, char[]
khá phổ biến. Ví dụ, đối với mã hóa tùy chỉnh, giải mã các chuỗi.
test(Object... objects)
rõ ràng khi có một chức năngtest()