Cấu trúc mảng truyền thống có các hạn chế:
Rất khó kiểm soát khi chỉ số các phần tử vượt ra khỏi phạm vi xác định. Ví dụ, trong chương trình C/C++ không thể cấm việc truy nhập đến phần tử ở ngoài phạm vi xác định như phần tử A[100] của mảng khai báo: int A[100];
Lứu ý:
Chỉ số các phần tử của mảng trong C/C++ và Java được bắt đầu từ 0. Lỗi vượt ra ngoài phạm vi của mảng là rất khó kiểm soát.Việc quản lý bộ nhớ của các cấu trúc mảng cũng rất phức tạp, nếu không tổ chức tốt thì chương trình lớn có thể dễ bị dừng vì thiếu bộ nhớ.
Trong Java, cấu trúc mảng là một lớp có biến dữ liệu thành phần công khai(public) length, xác định kích thước của mảng và có các phần tử với kiểu bất kỳ (nguyên thủy hoặc lớp đối tượng).
Khai báo các biến mảng
Các biến mảng có thể khai báo theo một trong hai dạng sau: <Kiểu các phần tử>[] <Tên mảng>;
<Kiểu các phần tử> <Tên mảng>[];
Trong đó <Kiểu các phần tử> có thể là kiểu nguyên thủy hoặc là kiểu lớp (tên lớp).
Lưu ý:
Kích thước của mảng chưa xác định khi khai báo,
Điều quan trọng cần phân biệt trong cấu trúc mảng của Java là việc khai báo biến mảng thì chưa hoàn toàn tạo ra cấu trúc đó mà mới khai báo cấu trúc để tham chiếu.
Ví dụ:
int mangInt[], bienInt; // (1)
BongDen[] dayBong, hangBong; // (2)
Lưu ý:
Khi ký hiệu [] đứng ngay sau kiểu khai báo thì tất cả các biến đứng sau đó đều là biến mảng, ví dụ ở (2), dayBong và hangBong đứng sau BongDen[] đều là biến mảng.
Tạo lập đối tượng mảng
Để tạo lập đối tượng mảng thì phải xác định số phần tử của mảng đó và phải sử dụng toán tử new.
<Tên mảng> = new <Kiểu các phần tử >[<Số phần tử>];
Trong đó <Kiểu các phần tử> là kiểu tương thích với kiểu mà mảng đã khai báo.
Giá trị cực tiểu của <Số phần tử> là 0, nghĩa là trong Java có thể tạo ra mảng 0 phần tử.
mangInt = new int[100]; // Mảng 100 phần tử kiểu int (3) dayBong = new BongDen[10];// Mảng 10 đối tượng của BongDen (4)
hangBong = new BongDen[15];// Mảng 15 đối tượng của BongDen
Nhiều khi chúng ta có thể kết hợp cả khai báo với tạo lập mảng như sau:
<Kiểu các phần tử 1> <Tên mảng>[] = new <Kiểu các phần tử 2>[<Số phần tử>];
Khai báo và tạo lập mảng <Tên mảng> kiểu <Kiểu các phần tử 1> để chứa <Số phầntử> các phần tử có <Kiểu các phần tử 2>.
Lưu ý:
<Kiểu các phần tử 1> và <Kiểu các phần tử 2> là hai kiểu tương thích với nhau.
Nếu mảng đó có kiểu nguyên thủy thì hai kiểu đó phải trùng nhau. Ngược lại, đối với kiểu lớp thì <Kiểu các phần tử 2> phải là lớp con của <Kiểu các phần tử 1>.
Tất nhiên một lớp cũng được xem là lớp con của chính nó.
Khi một mảng được tạo lập thì tất cả các phần tử của nó được khởi tạo giá trị mặc định (0 hoặc 0.0 đối với kiểu số, false đối với kiểu boolean, null cho kiểu lớp).
Ví dụ:
float mangFloat[] = new float[20];// Các phần tử được gán trị mặc định
Object[] dayDen = new BongDen[5];// Các phần tử được gán mặc định
null Khởi tạo các mảng
Java cung cấp cơ chế cho phép khai báo, tạo lập và gán ngay các giá trị ban đầu cho các phần tử của mảng:
<Kiểu các phần tử >[] <Tên mảng> = {<Các giá trị ban đầu>};
Ví dụ:
int[] mangInt = {1, 3, 5, 7, 9};
Tạo ra mangInt có 5 phần tử với phần tử đầu có giá trị là 1 (mangInt[0] = 1),
phần tử thứ hai là 3 (mangInt[1] = 3) , v.v.
Object[] dayDT = {new BongDen(), new BongDen(), null};
char[] charArr = {‘a’, ‘b’, ‘a’}; // mảng 3 ký tự và hoàn toàn khác với “aba”
Sử dụng mảng
Toàn bộ cấu trúc mảng được tham chiếu thông qua tên của mảng, còn các phần tử của nó có thể truy nhập được bởi toán tử [].Chỉ số các phần tử của mảng nhỏ nhất là 0 và nhỏ hơn kích thước của nó là <Tên
mảng>.length. Phần tử thứ i của mảng là phần tử có chỉ số i - 1 (<Tên mảng>[i-1]).
Ví dụ 3.1 Mô tả cách tạo ra năm mảng 15 các phần tử ngẫu nhiên và lưu lại năm giá trị cực tiểu của chúng để in ra màn hình.
Lưu ý, ở đây chúng ta có thể sử dụng các hàm của lớp Math để tính giá trị cực tiểu, sinh số ngẫu nhiên.
class Mang {
public static void main(String args[]){ // Khai báo và tạo lập mảng
double[] mang1 = new double[5]; // (1) double[] mang2 = new double[15]; // (2) for(int j = 0; j < mang1.length; ++j){ // (3) randomize(mang2); // Tạo lập mảng ngẫu nhiên mang1[j] = cucTieu(mang2); // Tìm giá trị cực tiểu } // In các giá trị cực tiểu ra màn hình // (4) for(int j = 0; j < mang1.length; ++j){ System.out.println(mang1[j]); } }
public static void randomize(double[] mang){ // (5) for(int j = 0; j < mang.length; ++j)
mang[j] = Math.random() * 100.0; }
public static double cucTieu(double[] mang){// (6) double giaTriMin = mang[0];
for(int j = 0; j < mang1.length; ++j)
giaTriMin = Math.min(giaTriMin, mang[j]); return giaTriMin;
} }
Mảng nhiều chiều
Các phần tử của mảng có thể tham chiếu tới các mảng khác. Trong Java, mảng của mảng (mảng nhiều chiều) được định nghĩa như sau: <Kiểu các phần tử>[][]...[] <Tên mảng>;
hoặc
<Kiểu các phần tử> <Tên mảng>[][]...[];
Toán tử [] có thể sử dụng ở cả hai vị trí, ví dụ
int[][] mang1; // Mảng hai chiều tương đương với
int mang1[][]; và cũng tương đương với
int[] mang1[]; Thông thường chúng ta có thể kết hợp cả khai báo với thiết lập mảng nhiều chiều tương tự như đối với mảng đơn.
int[][] mangA = new int[4][5]; // Ma trận có 4 hàng, 5 cột
Như thế mảng hai chiều còn được gọi là mảng của mảng. Phần tử thứ j của
mangA[i], j = 1, 2, ..., 5 được truy nhập bởi mangA[i][j]. Do vậy, kích thước của mangA là mangA.length = 4 và mỗi phần tử của nó lại là mảng có kích thước là mangA[i].length = 5, i = 1, 2, ..., 4.
double[][] maTran = { {1, 2, 3, 4}, // hàng 1
{0, 2, 0, 0}, // hàng 2 {0, 0, 3, 0}, // hàng 3 {0, 0, 0, 4}, // hàng 4 };
Lưu ý:
Các mảng trong mảng nhiều chiều không nhất thiết phải có số phần tử giống nhau. Ví dụ, mảng dayDen sau có 5 phần tử là các mảng có kích thước khác nhau.
BongDen[][] dayDen = {
{new BongDen(),null,new BongDen()},// Hàng có 3 phần tử (1) {null, new BongDen()}, // Hàng có 2 phần tử (2)
{}, // Hàng có 0 phần tử (3)
{new BongDen()}, // Hàng có 3 phần tử (4) {null} // Hàng chưa được tạo lập (5)
};
Lưu ý:
Như chúng ta đã khẳng định từ đầu, tất cả các lớp đều là lớp con củaObject, trong đó mảng cũng là lớp con của Object. Do vậy, giữa mảng và Object có thể thực hiện chuyển đổi kiểu:
+ Chuyển từ kiểu mảng về Object (Mở rộng kiểu), + Chuyển từ Object sang kiểu mảng ( Thu hẹp kiểu). Ví dụ:
class EpKieu{
static public void main(String[] args){ int[] a = new int[5];
Object o;
o = a; // int[] là con của Object int[] b = new int[5];
b = (int[])o; // Xem đối tượng của Object như là mảng int[] }
}
Ngoài ra cũng cần lưu ý thêm là cấu trúc mảng bảo toàn cấu trúc phân cấp giữa các lớp, nghĩa là nếu B là lớp con của lớp A thì B[] cũng là lớp con của lớp A[].