Files
My-Notes/笔记/CSharp/进阶/Hashtable.md
T
2026-06-21 09:51:55 +08:00

316 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Hashtable
概念:
`Hashtable` 是 C# 提供的一个==非泛型键值对集合==
它通过键 `key` 来查找值 `value`
简单理解:
像一本字典
用“词”查“解释”
`key``value`
命名空间:
```csharp
using System.Collections;
```
----
# 通常用法
1. 保存键值对数据
2. 通过唯一键快速查找对应值
3. 学习哈希表这种数据结构
4. 理解 `Dictionary<TKey, TValue>` 之前的非泛型写法
实际开发中:
新代码更推荐使用 `Dictionary<TKey, TValue>`
`Hashtable` 主要用于学习非泛型键值对集合
----
# 语法
创建:
```csharp
Hashtable table = new Hashtable();
```
添加:
```csharp
table.Add(, );
```
通过键取值:
```csharp
object value = table[];
```
修改:
```csharp
table[] = 新值;
```
数量:
```csharp
table.Count
```
----
# 基础案例
```csharp
using System;
using System.Collections;
Hashtable table = new Hashtable();
table.Add("name", "小明");
table.Add("age", 18);
table.Add("isVip", true);
Console.WriteLine(table["name"]);
Console.WriteLine(table["age"]);
Console.WriteLine(table["isVip"]);
```
理解:
1. `"name"``"age"``"isVip"` 是键
2. `"小明"``18``true` 是值
3. 通过键可以找到对应的值
----
# Add 和索引器
使用 `Add` 添加:
```csharp
Hashtable table = new Hashtable();
table.Add("id", 1001);
table.Add("name", "小明");
```
使用索引器添加或修改:
```csharp
table["score"] = 90; // 如果 key 不存在,就是新增
table["score"] = 100; // 如果 key 已存在,就是修改
```
区别:
1. `Add` 遇到重复键会报错
2. `table[key] = value` 遇到重复键会覆盖旧值
----
# 增删查改
增加:
```csharp
table.Add("level", 10);
```
删除:
```csharp
table.Remove("level");
table.Clear();
```
查找键:
```csharp
bool hasName = table.ContainsKey("name");
```
查找值:
```csharp
bool hasValue = table.ContainsValue("小明");
```
修改:
```csharp
table["name"] = "小红";
```
取值:
```csharp
string name = (string)table["name"];
```
----
# 遍历
遍历键值对:
```csharp
Hashtable table = new Hashtable();
table.Add("name", "小明");
table.Add("age", 18);
foreach (DictionaryEntry item in table)
{
Console.WriteLine(item.Key + " : " + item.Value);
}
```
只遍历键:
```csharp
foreach (object key in table.Keys)
{
Console.WriteLine(key);
}
```
只遍历值:
```csharp
foreach (object value in table.Values)
{
Console.WriteLine(value);
}
```
注意:
`Hashtable` 的遍历顺序不保证等于添加顺序
----
# key 不能重复
错误写法:
```csharp
Hashtable table = new Hashtable();
table.Add("name", "小明");
table.Add("name", "小红");
```
原因:
`Hashtable` 中的 key 必须唯一
重复添加同一个 key 会报错
如果想修改旧值:
```csharp
table["name"] = "小红";
```
----
# key 不能是 null
错误写法:
```csharp
Hashtable table = new Hashtable();
table.Add(null, "值");
```
原因:
`Hashtable` 的 key 不能为 `null`
但是 value 可以是 `null`
```csharp
table.Add("data", null);
```
----
# 取值时要判断 key 是否存在
```csharp
Hashtable table = new Hashtable();
table.Add("name", "小明");
if (table.ContainsKey("name"))
{
string name = (string)table["name"];
Console.WriteLine(name);
}
```
为什么要判断:
1. key 不存在时,`table[key]` 可能拿到 `null`
2. value 本身也可能是 `null`
3.`ContainsKey` 可以区分“没有这个键”和“这个键的值是 null”
----
# 取值时要类型转换
```csharp
Hashtable table = new Hashtable();
table.Add("age", 18);
int age = (int)table["age"];
```
原因:
非泛型 `Hashtable` 的 key 和 value 都是按 `object` 处理
取出来后通常需要强制类型转换
如果类型转错:
```csharp
string age = (string)table["age"];
```
会出错,因为 `"age"` 对应的值实际是 `int`
----
# 和 ArrayList 的区别
| 对比点 | ArrayList | Hashtable |
|---|---|---|
| 存储方式 | 单个元素 | 键值对 |
| 访问方式 | 通过下标 | 通过 key |
| key 是否存在 | 没有 key | key 必须唯一 |
| 常见用途 | 普通列表 | 字典式查找 |
| 泛型替代 | `List<T>` | `Dictionary<TKey, TValue>` |
----
# 常见错误
错误1:重复 Add 同一个 key
```csharp
table.Add("id", 1);
table.Add("id", 2);
```
应该改成:
```csharp
table["id"] = 2;
```
----
错误2:以为 Hashtable 有添加顺序
实际:
`Hashtable` 是根据 key 的哈希来组织数据
遍历顺序不保证是添加顺序
----
错误3:取值后忘记强转
```csharp
int age = table["age"];
```
应该写:
```csharp
int age = (int)table["age"];
```
----
# 注意
1. `Hashtable``System.Collections` 命名空间中
2. `Hashtable` 是非泛型键值对集合
3. key 不能重复
4. key 不能是 `null`
5. value 可以是 `null`
6. `Add` 重复 key 会报错
7. `table[key] = value` 可以新增,也可以覆盖旧值
8. 遍历顺序不保证等于添加顺序
9. 新项目通常优先使用 `Dictionary<TKey, TValue>`
----
# 一句话记忆
==Hashtable 是用 key 找 value 的非泛型键值对集合。==
再压缩一点:
==ArrayList 靠下标找,Hashtable 靠 key 找。==
----
# 面试/复习时怎么说
可以这样答:
“Hashtable 是 `System.Collections` 命名空间下的非泛型键值对集合,通过唯一 key 查找 value。
它的 key 不能重复,也不能为 nullvalue 可以为 null。
因为 key 和 value 都按 object 处理,所以取值时通常需要强制类型转换。新项目中一般更推荐使用泛型集合 `Dictionary<TKey, TValue>`。”
----
引用:
1. Microsoft Learn: [Hashtable Class](https://learn.microsoft.com/dotnet/api/system.collections.hashtable?view=net-9.0)
2. Microsoft Learn: [Hashtable.Add Method](https://learn.microsoft.com/en-us/dotnet/api/system.collections.hashtable.add?view=net-9.0)
3. Microsoft Learn: [Hashtable.Item Property](https://learn.microsoft.com/en-us/dotnet/api/system.collections.hashtable.item?view=net-9.0)
4. Microsoft Learn: [System.Collections Namespace](https://learn.microsoft.com/en-us/dotnet/api/system.collections?view=net-9.0)
#Hashtable
#哈希表
#集合
#进阶