Kiểu tham trị và kiểu tham chiếu
Khi chúng ta khai báo một biến kiểu tham trị (hầu hết các kiểu dữ liệu sơ cấp như kiểu int, double, char, v.v. đều là kiểu tham trị ngoại trừ kiểu String), trình biên dịch sẽ phát sinh mã để cấp phát một vùng nhớ đủ lớn để chứa giá trị tương ứng. Ví dụ khai báo biến x kiểu int:
int x;
Trình biên dịch sẽ phát sinh mã cấp phát biến x một vùng nhớ kích cỡ 4 byte (32 bit). Nếu gán x một giá trị:
x = 5;
giá trị 5 sẽ được đặt trong vùng nhớ vừa được cấp phát:
Khi chúng ta khai báo một biến kiểu tham chiếu (như kiểu String, array, class,…) thì trình biên dịch phát sinh mã để cấp phát một vùng nhớ đủ lớn để chứa địa chỉ của vùng nhớ chứa giá trị thực của biến. Ví dụ chúng ta khai báo biến kiểu String:
String str; str = "Hello there!";
lúc này sẽ có hai vùng nhớ, vùng nhớ chứa địa chỉ của vùng nhớ chứa giá trị Hello there! (ví dụ 3850) và vùng nhớ chứa giá trị Hello there!:
Nếu hình dung khái niệm này tương tự khái niệm con trỏ trong C, chúng ta có thể trực quan như sau:
Bây giờ chúng ta sẽ khai báo thêm biến y kiểu int và gán x đến y:
int x; x = 5; int y; y = x; x++;
lúc này biến y chứa một bản sao giá trị của biến x, những thay đổi của biến x (x++) sẽ không ảnh hưởng đến biến y.
Chúng ta cũng khai báo thêm biến strref kiểu String như sau:
String str; str = "Hello there!"; String strref; strref = str;
Lúc này hai vùng nhớ chứa địa chỉ của strref và str sẽ chứa cùng địa chỉ – là địa chỉ của vùng nhớ chứa Hello there!. Có thể hình dung về kiểu tham chiếu và tham trị từ các ví dụ trên một cách trực quan như sau:
Kiểu mảng
Mảng là một danh sách chứa các phần tử có cùng kiểu dữ liệu. Kiểu mảng là kiểu tham chiếu. Mảng có thể có một chiều hay nhiều chiều.
Mảng một chiều
Mảng một chiều là một danh sách chứa các phần tử cùng kiểu như các số nguyên, chuỗi,…Mỗi phần tử trong mảng được xác định tại một vị trí được gán chỉ số (index). Phần tử ở vị trí đầu tiên sẽ có chỉ số là 0, phần tử cuối cùng trong mảng có n phần tử có chỉ số là n – 1. Khai báo, truy cập (gán giá trị, hiển thị,…) các phần tử mảng dùng dấu ngoặc vuông.
Cú pháp
kiểu_dữ_liệu[] tên_mảng = new kiểu_dữ_liệu[kích cỡ hay số phần tử trong mảng];
Ví dụ khai báo mảng num chứa 5 số nguyên:
int[] num = new int [5];
Có thể hình dung mảng num một cách trực quan như sau:
Gán giá trị cho các phần tử trong mảng ta dùng cú pháp
tên_mảng [chỉ số của phần tử] = giá trị;
Ví dụ gán các giá trị số nguyên cho hai phần tử đầu tiên trong mảng num như sau:
num [0] = 7; // Gán giá trị 7 cho phần tử thứ nhất trong mảng num [1] = 19; // Gán 19 cho phần tử thứ hai
Có thể gán các phần tử khi khai báo mảng, ví dụ:
int[] num = {7,9};
Để truy cập phần tử trong mảng ta dùng cú pháp
tên_mảng [chỉ số phần tử];
Để trả về kích cỡ của mảng, chúng ta dùng thuộc tính length
int size = arrInt.length;// size = 5
Duyệt mảng
Chúng ta có thể duyệt qua các phần tử của một mảng nhờ các lệnh lặp. Ví dụ dùng lệnh for để hiển thị tất cả các phần tử của mảng arrInt như sau:
int[] arrInt = {2,4,8,9}; for (int i = 0; i < arrInt.length; i++) { int val = arrInt[i]; System.out.print(val + " "); }
Cũng có thể dùng lệnh foreach:
int[] arrInt = {2,4,8,9}; for (int val: arrInt) System.out.print(val + " ");
Kết quả: 2 4 8 9
Mảng như là tham số của phương thức
Mảng có thể được sử dụng như tham số của phương thức, ví dụ:
public class MyMainClass { public static void main(String[] args) { int[] arrInt = {2,4,8,9}; printArray(arrInt); } public static void printArray(int[] array) { for (int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); } } }
Mảng nhiều chiều
Cho đến thời điểm này chúng ta mới chỉ dừng lại ở mảng một chiều nhưng chúng ta có thể tạo ra mảng hơn một chiều. Có thể hình dung mảng một chiều chỉ là một dãy các phần tử, mảng hai chiều là một bảng các phần tử gồm các hàng và cột, mảng 3 chiều là một hình hộp, v.v.
Nếu khai báo mảng hai chiều, chúng ta có thể dùng cú pháp:
kiểu dữ liệu [][] biến mảng = new kiểu dữ liệu[số hàng][số cột];
Ví dụ sau khai báo và khởi tạo các giá trị cho mảng số thực (kiểu float) hai chiều arr2D có kích thước 7×5 như sau:
float[][] arr2D = new float[7][5]; arr2D[0][0] = 50.5f; arr2D[4][4] = 60.5f; arr2D[3][1] = 10.3f;
Có thể hình dung trực quan mảng arr2D như sau:
Đoạn mã sau sẽ hiển thị mảng arr2D ra màn hình:
for (int i = 0; i < 7; i++) { for (int j = 0; j < 5; j++) System.out.print(array2d[i][j] + " "); System.out.println(); }
Kết quả:
50.5 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 10.3 0.0 0.0 0.0 0.0 0.0 0.0 0.0 60.5 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
Bộ não chúng ta chỉ có thể hình dung được mảng có số chiều tối đa là 3 (vì chúng ta đang sống trong một thế giới 3 chiều). Với các mảng có số chiều lớn hơn 3, thật khó để hình dung một cách trực quan nhưng chúng ta có thể thao tác với các mảng này như đoạn mã minh họa mảng 4 chiều sau:
// khai báo mảng 4 chiều int[][][][] arr4D = new int[3][4][5][6]; // gán tất cả các phần tử của mảng đến giá trị 1729 for(int a = 0; a < 3; a++) { for(int b = 0; b < 4; b++) { for(int c = 0; c < 5; c++) { for(int d = 0; d < 6; d++) { arr4D[a][b][c][d] = 1729; } } } }