C# 中的字典与哈希表

Haider Ali 2023年10月12日
  1. C# 中的字典
  2. C# 中的哈希表
  3. C# 中的字典与哈希表
C# 中的字典与哈希表

本指南将讨论 C# 中 DictionaryHashtable 之间的区别。

要了解这些集合中哪个更好和更受欢迎,我们需要了解它们的基本原理。那么,让我们来看看与这两个集合相关的语法、特征、功能和方法。

在使用 C# 时,你应该更喜欢哪一个?哪个更好?

所有这些问题都将在下面得到解答。让我们潜入吧!

C# 中的字典

Dictionary 是一个通用集合。它将数据存储在键值对中,并且这个集合没有特定的顺序。

字典的语法如下:

Dictionary<TKey, TValue>

我们将数据值连同它们的键一起传递。让我们来看看字典的特点。

C# 中字典的特征

  1. 它存储键值对。
  2. 它的命名空间是 System.Collections.Generic
  3. Dictionary 中的键不能为空并且应该是唯一的。
  4. 但是,值可以为空值和重复值。
  5. 我们可以通过其对应的键访问数据值,例如,myDictionary[key]
  6. 所有元素都被认为是 KeyValuePair<TKey, TValue>

C# 中创建字典

你可以通过传递值的类型及其可以存储的相应键在 C# 中创建一个字典。查看以下代码,了解我们如何创建 Dictionary

IDictionary<int, string> rollno_names = new Dictionary<int, string>();
rollno_names.Add(1, "Ali");  // adding a key/value using the Add() method
rollno_names.Add(2, "Haider");
rollno_names.Add(3, "Saad");

// The following throws runtime exception: key already added.
// rollno_names.Add(3, "Rafay");

foreach (KeyValuePair<int, string> i in rollno_names)
  Console.WriteLine("Key: {0}, Value: {1}", i.Key, i.Value);

// creating a dictionary using collection-initializer syntax
var countries = new Dictionary<string, string>() {
  { "UK", "United Kingdom" }, { "USA", "United States of America" }, { "PK", "Pakistan" }
};

foreach (var j in countries) Console.WriteLine("Key: {0}, Value: {1}", j.Key, j.Value);

在上面的代码中,rollno_names 是一个 Dictionary,其中 int 为键数据类型,字符串为值数据类型,如下所示:

Dictionary<int, string>

这个特殊的 Dictionary 可以存储 int 键和字符串值。第二个字典是由集合初始化器创建的国家/地区。

它的键和值都是字符串数据类型。如果你尝试复制键值并将其设置为 null,你将获得运行时异常。

C# 中访问字典元素

你可以在索引器的帮助下访问 Dictionary 元素。你需要指定每个键来访问其对应的值。

ElementAt() 是另一种获取键值对的方法。看看下面的代码。

var countries = new Dictionary<string, string>() {
  { "UK", "UnitedKingdom" }, { "USA", "United State of America" }, { "PK", "Pakistan" }
};

Console.WriteLine(countries["UK"]);   // prints value of UK key
Console.WriteLine(countries["USA"]);  // prints value of USA key
// Console.WriteLine(countries["France"]); // runtime exception: key does not exist

// use ContainsKey() to check for the unknown key
if (countries.ContainsKey("France")) {
  Console.WriteLine(countries["France"]);
}

// use TryGetValue() to get a value of the unknown key
string result;

if (countries.TryGetValue("France", out result)) {
  Console.WriteLine(result);
}

// use ElementAt() to retrieve the key-value pair using the index
for (int i = 0; i < countries.Count; i++) {
  Console.WriteLine("Key: {0}, Value: {1}", countries.ElementAt(i).Key,
                    countries.ElementAt(i).Value);
}

在上面的代码中,你可以看到没有包含 France 的键值对。所以,上面的代码会给出一个运行时异常。

C# 中更新字典元素

通过在索引器中指定键,可以更改/更新键的值。如果在 Dictionary 中没有找到键,它将抛出 KeyNotFoundException 异常;因此,在访问任何未知键之前使用 ContainsKey() 函数。

看看下面的代码。

var countries = new Dictionary<string, string>() { { "UK", "London, Manchester, Birmingham" },
                                                   { "USA", "Chicago, New York, Washington" },
                                                   { "PK", "Pakistan" } };

countries["UK"] = "Europe";    // update value of UK key
countries["USA"] = "America";  // update value of USA key
// countries["France"] = "Western Europe"; //throws run-time exception: KeyNotFoundException

if (countries.ContainsKey("France")) {
  countries["France"] = "Western Europe";
}

C# 中删除字典元素

使用 Remove() 方法删除 Dictionary 中已经存在的键值对。使用 Clear() 方法删除所有 Dictionary 元素。

var countries = new Dictionary<string, string>() {
  { "UK", "UnitedKingdom" }, { "USA", "United state of America" }, { "PK", "Pakistan" }
};

countries.Remove("UK");  // removes UK
// countries.Remove("France"); //throws run-time exception: KeyNotFoundException

if (countries.ContainsKey("France")) {  // check key before removing it
  countries.Remove("France");
}

countries.Clear();

C# 中的哈希表

Dictionary 不同,Hashtable 是一个非泛型集合。它还存储键值对。

通过计算每个键的哈希码并将其存储在单独的内部存储桶中,它通过在访问值时匹配所提供键的哈希码来改进查找。看一下 Hashtable 的一些特征。

C# 中 Hashtable 的特征

  1. 键值对保存在 Hashtables 中。
  2. 它属于命名空间 SystemCollection
  3. 实现了 IDictionary 接口。
  4. 键不能为空,并且必须是不同的。
  5. 值可能重复或为空。
  6. 可以通过向索引器提供相关键来获取值,如 Hashtable[key]
  7. DictionaryEntry 对象用于存储元素。

C# 中创建一个哈希表

查看以下不言自明的代码以了解 Hashtable 的创建。

`Hashtable` rollno_names = new `Hashtable`();
rollno_names.Add(1, "Ali");  // adding a key/value using the Add() method
rollno_names.Add(2, "Haider");
rollno_names.Add(3, "Saad");

// The following throws runtime exception: key already added.
// rollno_names.Add(3, "Rafay");

foreach (DictionaryEntry i in rollno_names)
  Console.WriteLine("Key: {0}, Value: {1}", i.Key, i.Value);

// creating a `Hashtable` using collection-initializer syntax
var countries = new `Hashtable`() {
  { "UK", "UnitedKingdom" }, { "USA", "United State of America" }, { "PK", "Pakistan" }
};

foreach (DictionaryEntry j in countries) Console.WriteLine("Key: {0}, Value: {1}", j.Key, j.Value);

我们可以像 Dictionary 一样创建 Hashtable。唯一的区别是它是非泛型的,因此我们不必指定键的数据类型及其对应的值。

C# 的哈希表中添加字典

我们可以创建 Dictionary 的对象,并且通过在创建 Hashtable 时简单地传递该对象,我们可以在 Hashtable 中添加 Dictionary 键值对。

更新 C# 中的哈希表

通过在索引器中输入键,你可以从 Hashtable 检索现有键的值。由于 Hashtable 是一个非泛型集合(意味着键和值都没有数据类型),因此在从中获取值时需要将其类型转换为字符串。

看看下面的代码。

// creating a Hashtable using collection-initializer syntax
var countries = new Hashtable() {
  { { "UK", "UnitedKingdom" }, { "USA", "United State of America" }, { "PK", "Pakistan" } };

string countrynameUK = (string)countries["UK"];    // cast to string
string countrynameUSA = (string)countries["USA"];  // cast to string

Console.WriteLine(countrynameUK);
Console.WriteLine(countrynameUSA);

countries["UK"] = "Euorpe";    // update value of UK key
countries["USA"] = "America";  // update value of USA key

if (!countries.ContainsKey("France")) {
  countries["France"] = "Western Euorpe";
}

C# 中的哈希表中删除元素

Hashtable 的给定键值对使用 Remove() 方法删除。如果提供的键不存在于 Hashtable 中,则抛出 KeyNotfoundException 异常;因此,在删除密钥之前,请使用 ContainsKey() 方法查看它是否已经存在。

使用 Clear() 函数一次删除每个项目。

var countries = new Hashtable() {
  { "UK", "UnitedKingdom" }, { "USA", "United State of America" }, { "PK", "Pakistan" }
};

countries.Remove("UK");  // removes UK
// countries.Remove("France"); //throws run-time exception: KeyNotFoundException

if (countries.ContainsKey("France")) {  // check key before removing it
  countries.Remove("France");
}

countries.Clear();  // removes all elements

C# 中的字典与哈希表

Dictionary Hashtable
如果我们试图发现一个不存在的键,它要么返回要么抛出异常。 如果我们试图发现一个不存在的键,它会返回 null。
因为没有装箱和拆箱,它比 Hashtable 快。 由于需要装箱和拆箱,它需要比字典更长的时间。
线程安全仅适用于公共静态成员。 Hashtable 的成员都是线程安全的,
由于 Dictionary 是泛型类型,任何数据类型都可以与它一起使用(创建它时,我们必须指定键和值的数据类型)。 不是泛型类型。
具有强类型键和值的 Hashtable 实现称为 Dictionary 由于 Hashtables 是灵活类型的数据结构,因此可以添加任何键和值类型。

基于这些事实,我们可以说 Dictionary 优于 Hashtable。因为你可以将任何随机项插入 Dictionary<TKey, TValue> 并且你不必强制转换取出的值,所以你可以获得类型安全。

作者: Haider Ali
Haider Ali avatar Haider Ali avatar

Haider specializes in technical writing. He has a solid background in computer science that allows him to create engaging, original, and compelling technical tutorials. In his free time, he enjoys adding new skills to his repertoire and watching Netflix.

LinkedIn

相关文章 - Csharp Dictionary