Stack trong C#

Ở trong hướng dẫn trước chúng ta đã tìm hiểu về lớp Hashtable trong C# - một non-generic collection trong loạt bài hướng dẫn về Collection trong C#. Hashtable là một non-generic collection lưu trữ các phần tử có dạng khóa-giá trị với khóa đã được băm. Bạn có thể tìm hiểu Hashtable tại đây nếu như chưa xem:

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

Trong hướng dẫn này chúng ta sẽ tìm hiểu về lớp Stack trong C#. Stack (ngăn xếp) 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).

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

Stack cho phép giá trị null và giá trị trùng lặp. Nó cung cấp phương thức Push() để thêm giá trị và phương thức Pop() hoặc Peek() để truy xuất giá trị.

Stack

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

Stack trong C#

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

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

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

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

Phương thức Mô tả
Push Chèn một phần tử ở đầu Stack.
Peek Trả về phần tử hàng đầu từ Stack.
Pop Xóa và trả về các phần tử từ đầu Stack.
Contains Kiểm tra xem một phần tử có tồn tại trong Stack hay không.
Clear Loại bỏ tất cả các phần tử từ Stack.

Thêm giá trị vào Stack

Phương thức Push() thêm các giá trị vào Stack. Nó cho phép giá trị của bất kỳ kiểu dữ liệu nào.

Stack myStack = new Stack();
myStack.Push("Hello!!");
myStack.Push(null);
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
myStack.Push(4);
myStack.Push(5);

Truy cập các phần tử trong Stack

Duyệt tất cả phần tử trong Stack

Bạn có thể truy xuất các phần tử của Stack bằng nhiều cách khác nhau. Sử dụng câu lệnh foreach để duyệt Stack và nhận tất cả các phần tử theo kiểu LIFO.

Stack myStack = new Stack();
myStack.Push("Hello!!");
myStack.Push(null);
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
myStack.Push(4);
myStack.Push(5);

foreach (var item in myStack)
{
     Console.Write(item);
}

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

5
4
3
2
1

Hello!!

Phương thức Peek

Phương thức Peek() trả về giá trị cuối cùng (trên cùng) của stack. Gọi phương thức Peek() trên stack trống sẽ ném ra ngoại lệ UnlimitedOperationException. Vì vậy, luôn luôn kiểm tra các phần tử trong stack trước khi truy xuất bằng phương thức Peek().

Stack myStack = new Stack();
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
myStack.Push(4);
myStack.Push(5);

Console.WriteLine(myStack.Peek());
Console.WriteLine(myStack.Peek());
Console.WriteLine(myStack.Peek());

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

5
5
5

Phương thức Pop

Bạn cũng có thể truy xuất phần tử của stack bằng phương thức Pop(). Phương thức Pop() sẽ xóa và trả về giá trị được thêm vào cuối cùng vào stack. Gọi phương thức Pop() trên một ngăn xếp trống sẽ ném ra một ngoại lệ UnlimitedOperationException. Vì vậy, luôn luôn kiểm tra số lượng phần tử trong stack phải lớn hơn 0 trước khi gọi phương thức Pop().

Stack myStack = new Stack();
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
myStack.Push(4);
myStack.Push(5);

Console.Write("Number of elements in Stack: {0}", myStack.Count);

while (myStack.Count > 0)
{
     Console.WriteLine(myStack.Pop());
}

Console.Write("Number of elements in Stack: {0}", myStack.Count);

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

Number of elements in Stack: 5
5
4
3
2
1
Number of elements in Stack: 0

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

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

Stack myStack = new Stack();
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
myStack.Push(4);
myStack.Push(5);

Console.WriteLine(myStack.Contains(2)); 
Console.WriteLine(myStack.Contains(10)); 

Đâ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 Stack

Phương thức Clear() loại bỏ tất cả các phần tử khỏi stack.

Stack myStack = new Stack();
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
myStack.Push(4);
myStack.Push(5);

myStack.Clear(); // removes all elements

Console.Write("Number of elements in Stack: {0}", myStack.Count);

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

Number of elements in Stack: 0

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

  • Stack lưu trữ các giá trị theo kiểu LIFO (Last in First out). Phần tử được thêm vào cuối cùng sẽ là phần tử được đưa ra trước.
  • Sử dụng phương thức Push() để thêm các phần tử vào Stack.
  • Phương thức Pop() trả về và xóa các phần tử khỏi đỉnh Stack. Gọi phương thức Pop() trên Stack trống sẽ đưa ra một ngoại lệ.
  • Phương thức Peek() luôn trả về phần tử hàng đầu trong Stack.

Truy cập MSDN để biết thêm thông tin về các thuộc tính và phương thức của Stack.

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

Queue trong C# | Comdy
Queue trong C# là gì? Queue trong C# dùng để làm gì? Cách sử dụng Queue 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#.