Sự Khác Biệt Giữa List, LinkedList và ArrayList trong C# .NET

4 min read

Trong .NET, ba cấu trúc dữ liệu chính mà lập trình viên thường sử dụng để quản lý danh sách các phần tử là List<T>, LinkedList<T>, và ArrayList. Mỗi loại có ưu điểm và nhược điểm riêng, phù hợp với các tình huống khác nhau. Bài viết này sẽ giúp bạn hiểu rõ hơn về từng cấu trúc dữ liệu, sự khác biệt giữa chúng và khi nào nên sử dụng loại nào.

List<T>

List<T> là một danh sách generic type, lưu trữ các phần tử thuộc một kiểu dữ liệu xác định. Nó được triển khai dựa trên mảng động, cho phép thay đổi kích thước tự động khi thêm hoặc xóa phần tử.

  • Ưu điểm:
    • Truy cập phần tử nhanh thông qua chỉ số (O(1)).
    • Hỗ trợ LINQ và các thao tác generic type.
  • Nhược điểm:
    • Chèn hoặc xóa phần tử ở giữa danh sách có thể tốn kém (O(n)).

Ví dụ:





csharpCopy codeList<int> numbers = new List<int>();
numbers.Add(1);
numbers.Add(2);
numbers.Add(3);
Console.WriteLine(numbers[1]); // Output: 2

Hình ảnh minh họa List<T>:

Hình ảnh trên minh họa cách phần tử trong List<T> được lưu trữ liên tiếp trong bộ nhớ, và khi thêm phần tử mới thì bộ nhớ cho list thay đổi thế nào.

LinkedList<T>

LinkedList<T> là một danh sách liên kết kép (doubly linked list), nơi mỗi phần tử là một nút có chứa dữ liệu và liên kết tới nút tiếp theo và nút trước đó.

  • Ưu điểm:
    • Chèn/xóa phần tử nhanh ở đầu hoặc cuối danh sách (O(1)).
    • Không yêu cầu thay đổi kích thước của danh sách.
  • Nhược điểm:
    • Truy cập phần tử theo chỉ số chậm (O(n)).
    • Sử dụng nhiều bộ nhớ hơn do lưu trữ các liên kết.

Ví dụ:

csharpCopy codeLinkedList<int> linkedList = new LinkedList<int>();
linkedList.AddLast(1);
linkedList.AddLast(2);
linkedList.AddLast(3);
Console.WriteLine(linkedList.First.Value); // Output: 1

Hình ảnh minh họa LinkedList<T>:

Hình ảnh trên minh họa cấu trúc của một danh sách liên kết kép, với mỗi phần tử liên kết với nút trước và nút sau.

ArrayList

ArrayList là một danh sách non-generic, có thể lưu trữ các phần tử thuộc bất kỳ kiểu dữ liệu nào. Nó lưu trữ các phần tử dưới dạng object, điều này có thể dẫn đến chi phí hiệu suất do quá trình boxing/unboxing khi làm việc với kiểu giá trị.

  • Ưu điểm:
    • Linh hoạt về kiểu dữ liệu.
    • Dễ sử dụng trong các ứng dụng cũ hoặc khi không cần mạnh kiểu.
  • Nhược điểm:
    • Non-generic, dễ dẫn đến lỗi runtime.
    • Hiệu suất thấp hơn khi làm việc với kiểu giá trị.

Ví dụ:

csharpCopy codeArrayList arrayList1 = new ArrayList();
arrayList1.Add(1);arrayList1.Add(1);
arrayList1.Add(1);arrayList1.Add("Hello");...arrayList1.Add(true);
Console.WriteLine(arrayList1[3]); // Output: Hello

Hình ảnh minh họa ArrayList:

Hình ảnh trên thể hiện ArrayList arrayList1 được lưu trong bộ nhớ như thế nào: arrayList1 lưu trong Stack, các phần tử trong arrayList1 được lưu trong Heap

So Sánh Tóm Tắt

Đặc điểmList<T>LinkedList<T>ArrayList
Generic type Không
Truy cập phần tửO(1)O(n)O(1)
Chèn/xóa phần tửO(n) (ở giữa)O(1)O(n)
Bộ nhớHiệu quảTốn kém hơn do liên kếtTốn kém hơn do boxing
Hỗ trợ LINQKhông trực tiếpKhông

6. Khi Nào Nên Sử Dụng

  • Sử dụng List<T> khi bạn cần truy cập nhanh tới các phần tử và không phải thực hiện nhiều thao tác chèn/xóa giữa danh sách.
  • Sử dụng LinkedList<T> khi bạn cần chèn/xóa nhiều phần tử ở đầu hoặc cuối danh sách mà không quan tâm đến việc truy cập phần tử ngẫu nhiên.
  • Sử dụng ArrayList khi bạn cần lưu trữ các phần tử có kiểu dữ liệu khác nhau hoặc trong các ứng dụng cũ mà không yêu cầu mạnh kiểu.

7. Kết Luận

Sự lựa chọn giữa List<T>, LinkedList<T>, và ArrayList phụ thuộc vào nhu cầu cụ thể của ứng dụng. Hiểu rõ sự khác biệt giữa chúng sẽ giúp bạn tối ưu hóa hiệu suất và quản lý bộ nhớ một cách hiệu quả trong các dự án .NET của mình.

Liên kết tham khảo thêm:


Bài viết này cung cấp một cái nhìn tổng quan về sự khác biệt giữa ba cấu trúc dữ liệu phổ biến trong .NET. Hy vọng rằng thông qua bài viết này, bạn có thể lựa chọn được cấu trúc dữ liệu phù hợp nhất cho dự án của mình.

Avatar photo

Leave a Reply

Your email address will not be published. Required fields are marked *