Stack<T> cung cấp constructor nhận IEnumerable<T> cho phép tạo Stack mới từ một collection đã có. Lưu ý: Stack tuân theo nguyên tắc LIFO (Last In, First Out), nên thứ tự phần tử trong Stack mới sẽ **ngược lại** thứ tự trong collection nguồn khi duyệt bằng foreach.
Ví dụ 1: Tạo Stack<int> từ Stack khác qua ToArray()
using System;
using System.Collections.Generic;
public class Demo
{
public static void Main()
{
Stack<int> stack = new Stack<int>();
stack.Push(100);
stack.Push(200);
stack.Push(300);
stack.Push(400);
stack.Push(500);
stack.Push(600);
stack.Push(700);
stack.Push(800);
stack.Push(900);
stack.Push(1000);
Console.WriteLine("Các phần tử Stack gốc (LIFO - top đầu tiên)...");
foreach (int val in stack)
{
Console.WriteLine(val);
}
// Tạo Stack mới từ mảng của stack gốc
Stack<int> arr = new Stack<int>(stack.ToArray());
Console.WriteLine("\nCác phần tử Stack mới (từ ToArray)...");
foreach (int val in arr)
{
Console.WriteLine(val);
}
}
}
Kết quả
Các phần tử Stack gốc (LIFO - top đầu tiên)... 1000 900 800 700 600 500 400 300 200 100 Các phần tử Stack mới (từ ToArray)... 100 200 300 400 500 600 700 800 900 1000
Ví dụ 2: Stack<string>
using System;
using System.Collections.Generic;
public class Demo
{
public static void Main()
{
Stack<string> stack = new Stack<string>();
stack.Push("Katie");
stack.Push("Andy");
stack.Push("Ariane");
stack.Push("Justin");
Console.WriteLine("Các phần tử Stack gốc...");
foreach (string val in stack)
{
Console.WriteLine(val);
}
Stack<string> arr = new Stack<string>(stack.ToArray());
Console.WriteLine("\nCác phần tử Stack mới (từ ToArray)...");
foreach (string val in arr)
{
Console.WriteLine(val);
}
}
}
Kết quả
Các phần tử Stack gốc... Justin Ariane Andy Katie Các phần tử Stack mới (từ ToArray)... Katie Andy Ariane Justin
Giải thích thứ tự phần tử
📌 Quan trọng: Constructor
Stack<T>(IEnumerable<T>) thêm các phần tử theo thứ tự duyệt của IEnumerable. Vì stack.ToArray() trả về mảng theo thứ tự **top-to-bottom** (phần tử top ở index 0), Stack mới sẽ có thứ tự **ngược lại** stack gốc.
Stack gốc (Push: 1, 2, 3): Top -> 3, 2, 1 <- Bottom stack.ToArray() -> [3, 2, 1] (index 0 = top) Stack mới từ constructor IEnumerable: Push 3 -> Push 2 -> Push 1 Top -> 1, 2, 3 <- Bottom (NGƯỢC LẠI!)
Cách tạo Stack giữ nguyên thứ tự LIFO
// Cách 1: Reverse trước khi tạo
Stack<int> newStack = new Stack<int>(stack.Reverse());
// Hoặc
Stack<int> newStack = new Stack<int>(stack.ToArray().Reverse());
// Cách 2: Dùng constructor rồi Push lại (nếu cần logic phức tạp)
Stack<int> newStack = new Stack<int>();
foreach (var item in stack)
{
newStack.Push(item); // Push theo thứ tự top->bottom của stack gốc
}
// Kết quả: newStack có thứ tự giống stack gốc
Các constructor của Stack<T>
| Constructor | Mô tả |
|---|---|
Stack<T>() |
Rỗng, capacity mặc định |
Stack<T>(int capacity) |
Chỉ định capacity ban đầu |
Stack<T>(IEnumerable<T>) |
Tạo từ collection khác |
Lưu ý
- Stack<T> là generic, type-safe, trong
System.Collections.Generic - Non-generic
StacktrongSystem.Collectionscũng có constructor tương tự - ToArray() trả về mảng với phần tử top ở index 0
- foreach trên Stack duyệt từ top xuống bottom
- Khuyến nghị dùng
Stack<T>generic thay vì non-generic