Queue trong C#

Ở trong hướng dẫn trước chúng ta đã tìm hiểu về lớp Stack trong C# - một non-generic collection trong loạt bài hướng dẫn về Collection trong C#. Stack là một collection đặc biệt lưu trữ các phần tử theo kiểu LIFO (Last In First Out - Vào sau ra trước). Bạn có thể tìm hiểu Stack tại đây nếu như chưa xem:

Stack trong C# | Comdy
Stack trong C# là gì? Stack trong C# dùng để làm gì? Cách sử dụng Stack trong C#.

Trong hướng dẫn này chúng ta sẽ tìm hiểu về lớp Queue trong C#. Queue (hàng đời) là một collection đặc biệt lưu trữ các phần tử theo kiểu FIFO (First In First Out - Vào trước ra trước), Queue hoàn toàn ngược lại với Stack.

C# có hai loại Queue là non-genegic và generic. Trong hướng dẫn này chúng ta sẽ tìm hiểu về Queue non-generic.

Queue cho phép giá trị null và giá trị trùng lặp. Nó cung cấp phương thức Enqueue() để thêm giá trị và phương thức Dequeue() để truy xuất giá trị trong Queue.

Queue

Sơ đồ sau minh họa hệ thống phân cấp lớp Queue.

Queue trong C#

Các thành viên quan trọng của Queue

Các thuộc tính quan trọng của Queue:

Thuộc tính Mô tả
Count Trả về tổng số phần tử trong Queue.

Các phương thức quan trọng của Queue:

Phương thức Mô tả
Enqueue Chèn một phần tử ở đầu Queue.
Dequeue Xóa và trả về các phần tử từ đầu Queue.
Peek Trả về phần tử hàng đầu từ Queue.
Contains Kiểm tra xem một phần tử có tồn tại trong Queue hay không.
Clear Loại bỏ tất cả các phần tử từ Queue.
TrimToSize Thiết lập kích thước của Queue bằng số phần tử thực tế trong Queue.

Thêm phần tử vào Queue

Queue là một non-generic collection. Vì vậy, bạn có thể thêm các phần tử của bất kỳ kiểu dữ liệu nào vào Queue bằng phương thức Enqueue().

Ví dụ sau minh họa thêm phần tử vào Queue:

Queue queue = new Queue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");

Truy cập phần tử trong Queue

Phương thức Dequeue

Phương thức Dequeue() được sử dụng để truy xuất phần tử đầu tiên trong Queue. Dequeue() loại bỏ và trả về một phần tử đầu tiên từ hàng đợi vì Queue lưu trữ các phần tử theo thứ tự FIFO.

Gọi phương thức Dequeue() trên hàng đợi trống sẽ ném ngoại lệ UnlimitedOperationException. Vì vậy, luôn luôn kiểm tra xem tổng số phần tử trong hàng đợi phải lớn hơn 0 trước khi gọi phương thức Dequeue() trên Queue.

Queue queue = new Queue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");

Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);

while (queue.Count > 0)
{
    Console.WriteLine(queue.Dequeue());
}

Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);

Đây là kết quả khi biên dịch và chạy chương trình:

Number of elements in the Queue: 4
3
2
1
Four
Number of elements in the Queue: 0

Phương thức Peek

Phương thức Peek() luôn trả về phần tử đầu tiên của Queue mà không xóa nó khỏi hàng đợi.

Gọi các phương thức Peek()Dequeue() trên hàng đợi trống sẽ đưa ra một ngoại lệ khi thực thi "UnlimitedOperationException".

Queue queue = new Queue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");

Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);

Console.WriteLine(queue.Peek());
Console.WriteLine(queue.Peek());
Console.WriteLine(queue.Peek());

Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);

Đây là kết quả khi biên dịch và chạy chương trình:

Number of elements in the Queue: 4
3
3
3
Number of elements in the Queue: 4

Duyệt Queue

Bạn có thể duyệt một hàng đợi mà không cần loại bỏ các phần tử của nó bằng cách chuyển đổi thành một mảng, như dưới đây:

Queue queue = new Queue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");

Console.WriteLine("Number of elements in Queue: {0}", queue.Count);

foreach (var i in queue.ToArray())
{
    Console.WriteLine(i);
}

Console.WriteLine("Number of elements in Queue: {0}", queue.Count);

Đây là kết quả khi biên dịch và chạy chương trình:

Number of elements in Queue: 4
3
2
1
Four
Number of elements in Queue: 4

Kiểm tra phần tử tồn tại trong Queue

Phương thức Contains() kiểm tra xem một phần tử có tồn tại trong hàng đợi hay không. Nó trả về true nếu phần tử được chỉ định tồn tại; nếu không nó trả về false.

Queue queue = new Queue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");

Console.WriteLine(queue.Contains(2)); // true
Console.WriteLine(queue.Contains(100)); //false

Đây là kết quả khi biên dịch và chạy chương trình:

True
False

Xóa tất cả phần tử trong Queue

Phương thức Clear() xóa tất cả các phần tử khỏi hàng đợi.

Queue queue = new Queue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");

Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);

queue.Clear();

Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);

Đây là kết quả khi biên dịch và chạy chương trình:

Number of elements in the Queue: 4
Number of elements in the Queue: 0

Truy cập MSDN để biết thêm thông tin về các thành viên của Queue

Những điểm cần nhớ:

  • Hàng đợi lưu trữ các giá trị theo kiểu FIFO (First in First out). Phần tử được thêm vào trước sẽ được lấy ra trước.
  • Sử dụng phương thức Enqueue() để thêm các phần tử vào Queue
  • Phương thức Dequeue() trả về và loại bỏ các phần tử ở đầu tiền trong Queue. Gọi phương thức Dequeue() trên hàng đợi trống sẽ đưa ra một ngoại lệ.
  • Phương thức Peek() luôn trả về phần tử đầu tiên trong Queue.

Ở hướng dẫn tiếp theo chúng ta sẽ tìm hiểu về BitArray - cũng là một non-generic collection như Queue, được sử dụng để lưu trữ các phần tử bit.

BitArray trong C# | Comdy
BitArray trong C# là gì? BitArray trong C# dùng để làm gì? Cách sử dụng BitArray trong C#.


Bài viết liên quan:

Hướng dẫn này sẽ giúp bạn tìm hiểu về đọc ghi file (File I/O) trong C# và sử dụng các lớp tiện ích để đọc ghi file.

Reflection trong C#

  • 6 min read

Reflection trong C# là gì? Ứng dụng của Reflection trong C#. Cách khai báo và sử dụng Reflection trong C#.

Attribute trong C#

  • 7 min read

Attribute trong C# là gì? Có những loại attribute nào trong C#? Làm sao để sử dụng attribute trong C#.