Collections Framework (List, Set, Map)
Chào mừng bạn quay trở lại series "Chinh Phục Java"! Ở bài 5, chúng ta đã học về Mảng (Array). Mảng rất hữu ích, nhưng nó có một hạn chế lớn: kích thước cố định. Một khi đã tạo, bạn không thể thêm hay bớt phần tử. Trong thực tế, chúng ta thường cần các cấu trúc dữ liệu linh hoạt hơn. Java cung cấp một bộ công cụ cực kỳ mạnh mẽ để giải quyết vấn đề này. Đó chính là **Collections Framework**.
1. Collections Framework là gì?
Collections Framework là một tập hợp các lớp (class) và giao diện (interface). Nó cung cấp các cấu trúc dữ liệu được xây dựng sẵn để lưu trữ và thao tác với các nhóm đối tượng. Nó giống như một bộ dụng cụ đa năng cho việc xử lý dữ liệu. Thay vì phải tự xây dựng lại từ đầu, bạn có thể sử dụng ngay các cấu trúc đã được tối ưu hóa. Điều này giúp tiết kiệm thời gian và giảm thiểu lỗi.
Framework này được xây dựng xung quanh một vài interface cốt lõi. Trong bài này, chúng ta sẽ tập trung vào ba interface quan trọng và phổ biến nhất. Đó là: **List**, **Set**, và **Map**. Mỗi loại có những đặc điểm và trường hợp sử dụng riêng. Việc hiểu rõ chúng sẽ giúp bạn chọn đúng công cụ cho đúng công việc.
2. `List`: Danh sách có thứ tự, cho phép trùng lặp
Interface `List` đại diện cho một danh sách các phần tử có thứ tự. "Có thứ tự" nghĩa là các phần tử được lưu trữ và truy cập theo đúng vị trí mà bạn đã thêm chúng vào. Giống như Mảng, bạn có thể truy cập các phần tử thông qua chỉ số (index). Nhưng khác với Mảng, `List` có kích thước động. Bạn có thể dễ dàng thêm hoặc xóa các phần tử.
Đặc điểm quan trọng khác của `List` là nó **cho phép các phần tử trùng lặp**. Lớp triển khai phổ biến nhất của `List` là **`ArrayList`**. Nó rất hiệu quả cho việc truy cập ngẫu nhiên các phần tử.
import java.util.ArrayList;
import java.util.List;
public class ListExample {
public static void main(String[] args) {
// Khai báo một List, thường dùng ArrayList để triển khai
List fruits = new ArrayList<>();
// Thêm các phần tử vào danh sách
fruits.add("Táo");
fruits.add("Cam");
fruits.add("Chuối");
fruits.add("Táo"); // List cho phép phần tử trùng lặp
// Truy cập phần tử bằng chỉ số (bắt đầu từ 0)
System.out.println("Phần tử đầu tiên: " + fruits.get(0));
// In ra toàn bộ danh sách
System.out.println("Danh sách hoa quả: " + fruits);
// Xóa một phần tử
fruits.remove("Cam");
System.out.println("Danh sách sau khi xóa Cam: " + fruits);
}
}
3. `Set`: Tập hợp không có thứ tự, không cho phép trùng lặp
Interface `Set` đại diện cho một tập hợp các phần tử **duy nhất**. Đặc điểm quan trọng nhất của `Set` là nó **không cho phép các phần tử trùng lặp**. Nếu bạn cố gắng thêm một phần tử đã tồn tại vào `Set`, thao tác đó sẽ bị bỏ qua một cách âm thầm. Nó rất hữu ích khi bạn muốn đảm bảo rằng mỗi phần tử chỉ xuất hiện một lần.
Không giống như `List`, `Set` thường không đảm bảo về thứ tự của các phần tử. Bạn không thể truy cập phần tử bằng chỉ số. Lớp triển khai phổ biến nhất của `Set` là **`HashSet`**. Nó cung cấp hiệu năng rất cao cho các thao tác thêm, xóa và kiểm tra sự tồn tại.
import java.util.HashSet;
import java.util.Set;
public class SetExample {
public static void main(String[] args) {
// Khai báo một Set
Set uniqueNumbers = new HashSet<>();
uniqueNumbers.add(10);
uniqueNumbers.add(20);
uniqueNumbers.add(30);
uniqueNumbers.add(10); // Thao tác này sẽ bị bỏ qua vì 10 đã tồn tại
System.out.println("Tập hợp các số duy nhất: " + uniqueNumbers);
// Kiểm tra xem một phần tử có tồn tại không
boolean contains20 = uniqueNumbers.contains(20);
System.out.println("Có chứa số 20 không? " + contains20);
}
}
4. `Map`: Ánh xạ dạng Key-Value
Interface `Map` có cấu trúc khác biệt nhất. Nó không lưu trữ một danh sách các phần tử đơn lẻ. Thay vào đó, nó lưu trữ các cặp **key-value (khóa-giá trị)**. Mỗi giá trị được liên kết với một khóa duy nhất. `Map` giống như một cuốn từ điển. Bạn dùng "khóa" (từ) để tra cứu "giá trị" (nghĩa của từ). `Map` **không cho phép các khóa trùng lặp**.
`Map` cực kỳ hiệu quả cho việc tra cứu dữ liệu nhanh chóng. Thay vì phải duyệt qua cả danh sách để tìm một đối tượng, bạn có thể lấy nó ra ngay lập tức nếu biết khóa của nó. Lớp triển khai phổ biến nhất của `Map` là **`HashMap`**.
import java.util.HashMap;
import java.util.Map;
public class MapExample {
public static void main(String[] args) {
// Khai báo một Map, key là String, value là Integer
Map studentAges = new HashMap<>();
// Thêm các cặp key-value
studentAges.put("An", 20);
studentAges.put("Bình", 21);
studentAges.put("Cường", 20);
studentAges.put("An", 22); // Dòng này sẽ CẬP NHẬT giá trị của key "An"
// Lấy giá trị bằng key
int ageOfBinh = studentAges.get("Bình");
System.out.println("Tuổi của Bình là: " + ageOfBinh);
System.out.println("Toàn bộ Map: " + studentAges);
}
}
Kết luận
Bạn vừa được trang bị một bộ công cụ cực kỳ mạnh mẽ để làm việc với dữ liệu. Collections Framework cung cấp các cấu trúc dữ liệu linh hoạt và hiệu quả. Hãy nhớ: dùng `List` khi cần thứ tự và cho phép trùng lặp. Dùng `Set` khi cần các phần tử là duy nhất. Dùng `Map` khi cần tra cứu nhanh bằng khóa. Ở bài tiếp theo, chúng ta sẽ học cách xử lý các lỗi có thể xảy ra trong chương trình một cách chuyên nghiệp.
0 Bình luận
Vui lòng đăng nhập để gửi bình luận.