Hashtable trong C#

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

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

Trong hướng dẫn này chúng ta sẽ tìm hiểu về lớp Hashtable trong C#. Hashtable cũng tương tự như SortedList - là một non-generic collection thuộc namespace System.Collections. Nó cũng lưu trữ các cặp khóa - giá trị như SortedList.

Tuy nhiên Hashtable khác SortedList ở chỗ nó tạo mã băm của từng khóa và lưu trữ nó trong một nhóm nội bộ.

Nếu bạn chưa biết generic collection và non-generic collection trong C# là gì thì có thể tham khảo ở bài viết này:

Collection trong C# | Comdy
Collection trong C# là gì? Có những loại collection nào trong C#. Tác dụng và cách sử dụng của từng loại collection.

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

Hastable trong C#

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

Các phương thức quan trọng trong Hashtable:

Thuộc tính Miêu tả
Count Trả về tổng số cặp khóa / giá trị trong Hashtable.
IsReadOnly Trả về giá trị boolean cho biết liệu Hashtable có ở chế độ chỉ đọc hay không.
Item Trả về hoặc thiết lập giá trị được liên kết với khóa được chỉ định.
Keys Trả về được một ICollection của các khóa trong Hashtable.
Values Trả về được một ICollection của các giá trị trong Hashtable.
Phương thức Miêu tả
Add Thêm một phần tử với khóa và giá trị vào Hashtable.
Remove Xóa phần tử với khóa được chỉ định khỏi Hashtable.
Clear Loại bỏ tất cả các phần tử từ Hashtable.
Contains Kiểm tra xem Hashtable có chứa một khóa cụ thể không.
ContainsKey Kiểm tra xem Hashtable có chứa một khóa cụ thể không.
ContainsValue Kiểm tra xem Hashtable có chứa một giá trị cụ thể không.
GetHash Trả về mã băm cho khóa được chỉ định.

Thêm khóa-giá trị vào Hashtable

Phương thức Add() thêm một phần tử có khóa và giá trị vào Hashtable. Khóa và giá trị có thể thuộc bất kỳ loại dữ liệu nào. Khóa không thể là null trong khi giá trị có thể là null.

Ví dụ sau minh họa thêm khóa và giá trị vào Hashtable:

Hashtable ht = new Hashtable();

ht.Add(1, "One");
ht.Add(2, "Two");
ht.Add(3, "Three");
ht.Add(4, "Four");
ht.Add(5, null);
ht.Add("Fv", "Five");
ht.Add(8.5F, 8.5);

Bạn cũng có thể gán khóa và giá trị tại thời điểm khởi tạo bằng cú pháp khởi tạo đối tượng như sau:

Hashtable ht = new Hashtable()
{
	{ 1, "One" },
	{ 2, "Two" },
	{ 3, "Three" },
	{ 4, "Four" },
	{ 5, null },
	{ "Fv", "Five" },
	{ 8.5F, 8.5 }
};

Hashtable có thể bao gồm tất cả các phần tử của Dictionary như ví dụ dưới đây:

Dictionary<int, string> dict = new Dictionary<int, string>();

dict.Add(1, "one");
dict.Add(2, "two");
dict.Add(3, "three");

Hashtable ht = new Hashtable(dict);
Lưu ý: phương thức Add() sẽ đưa ra một ngoại lệ nếu bạn cố gắng thêm một khóa đã tồn tại trong Hashtable. Vì vậy, luôn luôn kiểm tra khóa bằng phương thức Contains() hoặc ContainsKey() trước khi thêm cặp khóa-giá trị vào Hashtable.

Truy cập Hashtable

Bạn có thể lấy lại giá trị của một khóa hiện có từ Hashtable bằng cách sử dụng bộ chỉ mục. Xin lưu ý rằng bộ chỉ mục Hashtable yêu cầu khóa.

Ví dụ dưới đây minh họa truy cập giá trị của Hashtable:

Hashtable ht = new Hashtable();

ht.Add(1, "One");
ht.Add(2, "Two");
ht.Add(3, "Three");
ht.Add(4, "Four");
ht.Add("Fv", "Five");
ht.Add(8.5F, 8.5F);
    
string strValue1 = (string)ht[2];
string strValue2 = (string)ht["Fv"];
float fValue = (float) ht[8.5F];

Console.WriteLine(strValue1);
Console.WriteLine(strValue2);
Console.WriteLine(fValue);

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

Two
Five
8.5
Lưu ý: Hashtable là một non-generic collection vì vậy nó có thể chứa khóa và giá trị của bất kỳ loại dữ liệu nào. Vì vậy, các giá trị phải được ép kiểu dữ liệu thích hợp nếu không nó sẽ gây ra lỗi khi biên dịch.

Các phần tử băm là các cặp khóa-giá trị được lưu trữ trong DictionaryEntry. Vì vậy, bạn ép kiểu từng phần tử trong Hashtable sang DictionaryEntry. Sử dụng câu lệnh foreach để duyệt Hashtable, như ví dụ dưới đây:

Hashtable hashtable = new Hashtable()
{
	{ 1, "One" },
	{ 2, "Two" },
	{ 3, "Three" },
	{ 4, "Four" },
	{ 5, null },
	{ "Fv", "Five" },
	{ 8.5F, 8.5 }
};

foreach (DictionaryEntry item in hashtable)
{
	Console.WriteLine("key:{0}, value:{1}",item.Key, item.Value);
}

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

Key: Fv, Value: Five
Key: 8.5, Value: 8.5
Key: 5, Value:
Key: 4, Value: Four
Key: 3, Value: Three
Key: 2, Value: Two
Key: 1, Value: One

Hashtable có thuộc tính KeysValues chứa tất cả các khóa và giá trị tương ứng. Bạn có thể sử dụng các thuộc tính này để lấy các khóa và giá trị.

Hashashtableable hashashtableable = new Hashashtableable();
{
	{ 1, "One" },
	{ 2, "Two" },
	{ 3, "Three" },
	{ 4, "Four" },
	{ 5, null },
	{ "Fv", "Five" },
	{ 8.5F, 8.5 }
};

foreach (var key in hashtable.Keys)
{
	Console.WriteLine("Key:{0}, Value:{1}", key, hashtable[key]);
}

Console.WriteLine("***All Values***");
        
foreach (var value in hashtable.Values)
{
	Console.WriteLine("Value:{0}", value);
}

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

Key:Fv, Value:Five
Key:8.5, Value:8.5
Key:5, Value:
Key:4, Value:Four
Key:3, Value:Three
Key:2, Value:Two
Key:1, Value:One
***All Values***
Value:Five
Value:8.5
Value:
Value:Four
Value:Three
Value:Two
Value:One

Xóa các phần tử trong Hashtable

Phương thức Remove() xóa phần tử bằng khóa được chỉ định khỏi Hashtable.

Ví dụ sau sẽ minh họa xóa phần tử trong Hashtable:

Hashtable hashtable = new Hashtable()
{
	{ 1, "One" },
	{ 2, "Two" },
	{ 3, "Three" },
	{ 4, "Four" },
	{ "Fv", "Five" },
	{ 8.5F, 8.5 }
};

hashtable.Remove("Fv");

foreach (var key in hashtable.Keys)
{
	Console.WriteLine("Key:{0}, Value:{1}", key, hashtable[key]);
}

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

Key:8.5, Value:8.5
Key:4, Value:Four
Key:3, Value:Three
Key:2, Value:Two
Key:1, Value:One

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

Các phương thức Contains()ContainsKey() kiểm tra xem khóa đã chỉ định có tồn tại trong Hashtable hay không.

Phương thức ContainsValue() kiểm tra xem giá trị được chỉ định có tồn tại trong Hashtable hay không.

Ví dụ dưới đây minh họa kiểm tra tồn tại khóa và giá trị trong Hashtable:

Hashashtableable hashtable = new Hashashtableable()
{
	{ 1, "One" },
	{ 2, "Two" },
	{ 3, "Three" },
	{ 4, "Four" }
};

Console.WriteLine(hashtable.Contains(2));// returns true
Console.WriteLine(hashtable.ContainsKey(2));// returns true
Console.WriteLine(hashtable.Contains(5)); //returns false
Console.WriteLine(hashtable.ContainsValue("One")); // returns true		

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

True
True
False
True

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

Phương thức Clear() loại bỏ tất cả các cặp khóa-giá trị trong Hashtable. Ví dụ dưới đây minh họa điều này:

Hashashtableable hashtable = new Hashashtableable()
{
	{ 1, "One" },
	{ 2, "Two" },
	{ 3, "Three" },
	{ 4, "Four" },
	{ 5, null },
	{ "Fv", "Five" },
	{ 8.5F, 8.5 }
};

hashtable.Clear(); // removes all elements
Console.WriteLine("Total Elements: {0}", hashtable.Count);

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

Total Elements: 0

Sự khác biệt giữa Hashtable và Dictionary

Bảng sau liệt kê sự khác biệt giữa Hashtable và Dictionary trong C#.

Hashtable Dictionary
Hashtable là non-generic collection thuộc namespace System.Collections. Dictionary là generic collection thuộc namespace System.Collections.Generic.
Hashtable là một non-generic collection, điều này có nghĩa là nó lưu trữ các cặp khóa-giá trị của bất kỳ kiểu dữ liệu nào. Dictionary là một generic collection. Vì vậy, nó có thể lưu trữ các cặp khóa-giá trị của các kiểu dữ liệu cụ thể.
Hashtable là thread safe. Chỉ các thành viên public static của Dictionary là thread safe.
Hashtable trả về null nếu chúng ta cố gắng tìm một khóa không tồn tại. Dictionary ném một ngoại lệ nếu chúng ta cố gắng tìm một khóa không tồn tại.
Truy xuất dữ liệu chậm hơn Dictionary vì phải unboxing. Truy xuất dữ liệu nhanh hơn Hashtable vì định kiểu mạnh.

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

  • Hashtable lưu trữ các cặp khóa-giá trị của bất kỳ kiểu dữ liệu nào trong đó khóa phải là duy nhất.
  • Khóa Hashtable không thể null trong khi giá trị có thể là null.
  • Hashtable lấy một phần tử bằng cách so sánh mã băm của các khóa. Vì vậy, nó có hiệu suất chậm hơn so với Dictionary.
  • Hashtable sử dụng trình băm mặc định là Object.GetHashCode(). Bạn cũng có thể sử dụng một trình băm tùy chỉnh.
  • Sử dụng DictionaryEntry với câu lệnh foreach để duyệt Hashtable.

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

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#.
Lập Trình C#Lập Trình C# Cơ Bản
Bài Viết Liên Quan:
Tạo tập tin Zip với .NET 5
Trung Nguyen 11/11/2021
Tạo tập tin Zip với .NET 5

Trong bài viết này, chúng ta sẽ tìm hiểu lớp tiện ích ZipFile trong C#, cách nén tập tin và thư mục, cùng với giải nén tập tin zip.

Đọc và ghi file Excel trong C#
Trung Nguyen 29/10/2021
Đọc và ghi file Excel trong C#

Bài viết này sẽ giới thiệu cách đơn giản nhất mà tôi đã tìm thấy để đọc và ghi file Excel bằng C# sử dụng ExcelMapper.

Làm việc với PriorityQueue của .NET 6
Trung Nguyen 25/10/2021
Làm việc với PriorityQueue của .NET 6

Bài viết này sẽ giúp bạn tìm hiểu PriorityQueue của .NET 6 là gì, cách chúng ta thêm các phần tử và cách chúng ta có thể xếp hàng lại cho các phần tử.

Hướng dẫn nhanh và ví dụ về pattern matching trong C#
Trung Nguyen 23/10/2021
Hướng dẫn nhanh và ví dụ về pattern matching trong C#

Bài viết này sẽ trình bày một số ví dụ về pattern matching hữu ích và bạn có thể xem xét sử dụng trong các dự án hiện tại hoặc tương lai của bạn.