Trong C#, collections là các cấu trúc dữ liệu được sử dụng để lưu trữ và quản lý các nhóm đối tượng. C# cung cấp nhiều loại collections khác nhau để phù hợp với các yêu cầu cụ thể của lập trình viên. Dưới đây là phân loại và giới thiệu chi tiết về các loại collections:
1. Non-Generic Collections
Được định nghĩa trong namespace System.Collections. Những collection này không yêu cầu kiểu dữ liệu cụ thể cho các phần tử mà chúng lưu trữ.
Các loại phổ biến:
- ArrayList: Lưu trữ các phần tử không có kiểu cụ thể. Kích thước có thể thay đổi linh hoạt.
- Ưu điểm: Dễ sử dụng khi không biết kiểu dữ liệu chính xác.
- Nhược điểm: Hiệu suất kém hơn so với collections generic và không an toàn kiểu dữ liệu.
- Hashtable: Lưu trữ các cặp key-value. Các khóa không thể trùng lặp.
- Queue: Thực hiện theo cơ chế FIFO (First In First Out).
- Stack: Thực hiện theo cơ chế LIFO (Last In First Out).
2. Generic Collections
Được định nghĩa trong namespace System.Collections.Generic. Các collection này yêu cầu xác định kiểu dữ liệu ngay khi khai báo, giúp an toàn kiểu và hiệu suất cao hơn.
Các loại phổ biến:
- List<T>:
- Lưu trữ danh sách các phần tử có kiểu xác định.
- Tương tự như ArrayList nhưng an toàn kiểu.
List<int> numbers = new List<int> { 1, 2, 3 };
numbers.Add(4); // Thêm phần tử
- Dictionary<TKey, TValue>:
- Lưu trữ các cặp key-value với kiểu xác định.
- Các key là duy nhất.
Dictionary<int, string> students = new Dictionary<int, string>();
students.Add(1, "Alice");
- Queue<T>:
- Queue generic với kiểu dữ liệu xác định.
- Stack<T>:
- Stack generic với kiểu dữ liệu xác định.
- HashSet<T>:
- Một tập hợp không chứa các phần tử trùng lặp.
3. Concurrent Collections
Được định nghĩa trong namespace System.Collections.Concurrent. Những collection này được thiết kế để hoạt động tốt trong môi trường đa luồng (multi-threading).
Các loại phổ biến:
- ConcurrentBag<T>: Hỗ trợ thêm/xóa các phần tử không có thứ tự cụ thể.
- ConcurrentDictionary<TKey, TValue>: Dictionary hỗ trợ thread-safe.
- BlockingCollection<T>: Được sử dụng để điều phối sản xuất và tiêu thụ trong các ứng dụng đa luồng.
4. Specialized Collections
Được định nghĩa trong namespace System.Collections.Specialized. Được sử dụng trong các trường hợp đặc biệt.
Các loại phổ biến:
- StringCollection: Một collection chỉ lưu trữ các chuỗi.
- NameValueCollection: Lưu trữ các cặp key-value nhưng hỗ trợ nhiều giá trị cho một key.
5. Immutable Collections
Được định nghĩa trong namespace System.Collections.Immutable. Các collection này không thể thay đổi sau khi được tạo ra, rất hữu ích trong các ứng dụng không cho phép chỉnh sửa dữ liệu (immutable).
Các loại phổ biến:
- ImmutableList<T>
- ImmutableDictionary<TKey, TValue>
- ImmutableArray<T>
So sánh Non-Generic và Generic
Tiêu chí |
Non-Generic |
Generic |
An toàn kiểu |
Không an toàn |
An toàn |
Hiệu suất |
Thấp hơn |
Cao hơn |
Kiểu dữ liệu |
Không yêu cầu cụ thể |
Phải xác định |
Tính phổ biến |
Ít phổ biến hơn |
Phổ biến hơn |
Khi nào nên dùng loại nào?
- Non-Generic: Khi cần làm việc với kiểu dữ liệu hỗn hợp (hiếm gặp).
- Generic: Nên ưu tiên sử dụng vì an toàn và hiệu suất cao.
- Concurrent: Khi làm việc trong môi trường đa luồng.
- Immutable: Khi cần đảm bảo tính bất biến của dữ liệu.
Bài tập 1:
Đề bài: Viết chương trình sử dụng Queue<T> để quản lý hàng đợi khách hàng tại ngân hàng.
Các chức năng:
- Thêm khách hàng mới vào hàng đợi.
- Gọi khách hàng tiếp theo.
- Hiển thị danh sách khách hàng trong hàng đợi.
Bài tập 2: Đảo ngược chuỗi bằng Stack
Đề bài: Viết chương trình sử dụng Stack để đảo ngược một chuỗi bất kỳ do người dùng nhập vào.
Ví dụ:
- Nhập: "Hello"
- Kết quả: "olleH"
Tham khảo: https://tedu.com.vn/lap-trinh-c/cnet-can-ban-hieu-biet-ve-cac-collection-trong-net-framework-90.html
Tác giả: Bạch Ngọc Toàn
Chú ý: Tất cả các bài viết trên TEDU.COM.VN đều thuộc bản quyền TEDU, yêu cầu dẫn nguồn khi trích lại trên website khác.