Nội dung bài viết
Lê Minh Trung Cũng như các ngôn ngữ lập trình khác, Java hỗ trợ bộ cấu trúc điều khiển gồm có: cấu trúc rẽ nhánh, cấu trúc vòng lặp, cấu trúc nhảy… để giúp lập trình viên có thể linh hoạt và dễ dàng thực thi ý tưởng của mình. Bài viết trình bày về cấu trúc rẽ nhánh trong Java như if-else, switch-case.

Giới thiệu

Cũng như các ngôn ngữ lập trình khác, Java hỗ trợ bộ cấu trúc điều khiển gồm có: cấu trúc rẽ nhánh, cấu trúc vòng lặp, cấu trúc nhảy… để giúp lập trình viên có thể linh hoạt và dễ dàng thực thi ý tưởng của mình. Trong bài viết này, chúng ta sẽ đi tìm hiểu cấu trúc rẽ nhánh.

Tiền đề bài viết

Bài viết nằm trong chủ đề Java của STDIO, với mong muốn hỗ trợ những người đang tìm hiểu về ngôn ngữ lập trình Java.

Đối tượng hướng đến

Đối tượng hướng đến là các lập trình viên đang tìm hiểu về ngôn ngữ lập trình Java, có kiến thức cơ bản về lập trình C/C++ hoặc các ngôn ngữ lập trình khác là một lợi thế.

Cấu trúc rẽ nhánh if, if-else

Cấu trúc rẽ nhánh cơ bản dạng if

Cú pháp

if(conditional){
	statement1;
	statement2;
}

Mô tả thực thi

ss_1

Nếu conditional trả về true, thực thi khối statement1 và statement2. Nếu conditional trả về false thì bỏ qua khối này.

Cấu trúc rẽ nhánh mở rộng dạng if-else

Cú pháp

if(conditional){
	statement1;
	statement2;
}
else{
	statement7;
    statement8;
}

Mô tả thực thi

ss_2

Nếu conditional trả về true, thực thi khối statement1 và statement2. Nếu conditional trả về false thì thực thi khối statement7 và statement8.

Ví dụ

int x = 3;
if(x > 2){
	System.out.println("X > 2");
}
else{
	System.out.println("X <= 2");
}

Ngoài ra, ngôn ngữ lập trình Java hỗ trợ cấu trúc dạng mở rộng hơn, gồm nhiều cấu trúc if-else lồng nhau dạng như sau:

if(conditional){
	statement1;
}
else{
    if(conditional2){
		statement2;
	}
	else{
		statement3;
    }
}

Nếu conditional trả về true, thực thi statement1, nếu conditional trả về false thì xét tiếp khối else như sau: nếu conditional2 trả về true, thì thực thi statement2, nếu conditional2 trả về false thì thực thi statement3.

Các cấu trúc rẽ nhánh dạng cao hơn (nhiều if-else lồng nhau) cũng được thực thi tương tự như trên.

Cấu trúc rẽ nhánh switch-case

Quan điểm sử dụng

Trong một vài trường hợp, bạn dùng quá nhiều cấu trúc rẽ nhánh dạng if-else, và điều kiện của các mã xử lý này có điểm tương đồng. Bạn có thể nghĩ đến việc sử dụng cấu trúc switch-case.

Ví dụ bạn cần xét các tháng trong 1 năm. Chúng ta sẽ cần khá nhiều cấu trúc rẽ nhánh dạng if, if-else hoặc các dạng mở rộng hơn để xét tất cả 12 tháng. Tôi sẽ trình bày cụ thể ví dụ này ở trong phần Ví dụ của cấu trúc rẽ nhánh dạng switch-case.

Cấu trúc switch-case

Cú pháp

switch(expression){
    case (value1) :
        statement1;
        break;
    case (value2) :
        statement2;
        break;
    default:
        statement4;
        break;
}

Mô tả thực thi

ss_3

Bước 1: Tính toán biểu thức (expression).

Bước 2: So sánh từng trường hợp (case) theo thứ tự từ trên xuống, với kết quả của expression đã tính toán ở bước 1.Nếu một trong các case thỏa mãn (bằng) với expression, thì thực thi khối mã xử lý trong case đó. Sau đó đến bước 3. Nếu không, thực thi khối default.

Bước 3: Sau khi thực hiện khối , có thể là một trong các khối case hoặc default (tùy theo giá trị của expression), sẽ thực hiện break;, có nghĩa là sẽ thoát khỏi khối switch-case. Nếu chưa rõ, bạn có thể xem chi tiết ở phần Ví dụ.

Lưu ý

Bạn có thể có nhiều hơn 2 case, trong phần cú pháp và mô tả thực thi, tôi chỉ thực hiện với 2 case để đảm bảo tính ngắn gọn và dễ hiểu của bài viết.
Trong cú pháp của switch-case, bạn có thể không viết phần default. Khi đó, sau khi kiểm tra nếu không có case nào thỏa mãn, chương trình sẽ tự động thoát ra khỏi khối lệnh switch-case.

Ví dụ

Ta sẽ đi vào so sánh 2 ví dụ, sử dụng switch-case và sử dụng nhiều cấu trúc dạng if.

Đoạn mã sử dụng cấu trúc dạng if

int month = 2;
if(month == 1)                 System.out.println("January");
if(month == 2)                 System.out.println("February");
if(month == 3)                 System.out.println("March");
if(month == 4)                 System.out.println("April");
if(month == 5)                 System.out.println("May");
if(month == 6)                 System.out.println("June");
if(month == 7)                 System.out.println("July");
if(month == 8)                 System.out.println("August");
if(month == 9)                 System.out.println("September");
if(month == 10)                System.out.println("October");
if(month == 11)                System.out.println("November");
if(month == 12)                System.out.println("December");
if(month < 1 | month > 12)     System.out.println("Error");

Đoạn mã sử dụng cấu trúc dạng switch-case

int month = 2;
switch(month){
case 1:		
	System.out.println("January");	break;
case 2:		
	System.out.println("February");	break;
case 3:		
	System.out.println("March");	break;
case 4:		
	System.out.println("April");	break;
case 5:
	System.out.println("May");		break;
case 6:
	System.out.println("June");		break;
case 7:		
	System.out.println("July");		break;
case 8:
	System.out.println("August");	break;
case 9:
	System.out.println("September");break;
case 10:
	System.out.println("October");	break;
case 11:
	System.out.println("November");	break;
case 12:
	System.out.println("December"); break;
default:
	System.out.println("Error"); 	break;
}

Trong mỗi case, sau khi đoạn mã thực thi, bạn phải thêm vào mã xử lý break;. Việc này để tránh trường hợp chương trình tiếp tục nhảy xuống các case không mong muốn ở dưới. Ví dụ nếu bạn không để break; trong đoạn case có giá trị month = 2. Thì chương trình sẽ tiếp tục đi vào case có giá trị là month = 3. Đó có thể là điều mà bạn không mong muốn.

Việc sử dụng switch-case có thể không làm mã nguồn trở nên ngắn hơn, nhưng nó giúp cho mã nguồn rõ ràng, dễ hiểu hơn, đôi khi cải thiện hiệu suất hoạt động của chương trình. Ở ví dụ trên ta thấy rằng, chương trình viết theo cấu trúc if sẽ phải kiểm tra 13 lần cho mọi trường hợp. Tuy nhiên với cấu trúc switch-case chỉ kiểm tra đến case có giá trị 2, nghĩa là chỉ kiểm tra 2 lần.

THẢO LUẬN
ĐÓNG