C# 代码(`Hashtable` 和 `SortedList`)

一、Hashtable(哈希表)

1. 基本概念
  • 非泛型集合:存储键值对(object 类型),通过哈希算法实现快速查找。

  • 线程安全:默认非线程安全,可通过 Hashtable.Synchronized 创建线程安全版本。

  • 键的唯一性:键必须唯一,且不可为 null(值可为 null)。

2. 创建与初始化
// 创建空的 Hashtable
Hashtable hashtable = new Hashtable();
​
// 创建并初始化
Hashtable table = new Hashtable() {
    { 0, "这是0" },
    { "1", "这是1" },
    { true, "这是true" },
    { 'a', "aaaa" }
};
3. 常用属性与方法
操作 代码示例 说明
添加键值对 table.Add(123, "123"); 添加键值对(键不存在时)。
通过键访问值 string value = (string)table[true]; 通过键获取值(返回 object,需强制类型转换)。
通过键设置值 table['a'] = "new value"; 修改已存在键对应的值。
判断键是否存在 bool hasKey = table.ContainsKey(0); 检查是否包含指定键。
判断值是否存在 bool hasValue = table.ContainsValue("123"); 检查是否包含指定值。
删除键值对 table.Remove(true); 删除指定键对应的元素。
清空哈希表 table.Clear(); 移除所有键值对。
获取元素数量 int count = table.Count; 返回哈希表中键值对的数量。
获取所有键 ICollection keys = table.Keys; 返回所有键的集合。
获取所有值 ICollection values = table.Values; 返回所有值的集合。
4. 遍历 Hashtable
// 遍历所有键值对
foreach (DictionaryEntry entry in table) {
    Console.WriteLine($"Key: {entry.Key}, Value: {entry.Value}");
}
​
// 单独遍历键或值
foreach (var key in table.Keys) {
    Console.WriteLine(key);
}
​
foreach (var value in table.Values) {
    Console.WriteLine(value);
}
5. 注意事项
  • 装箱拆箱:由于存储 object 类型,值类型(如 intbool)会发生装箱拆箱,影响性能。

  • 键的哈希码:键必须正确实现 GetHashCode()Equals() 方法,否则可能无法正确查找。

  • 无序性:遍历时元素顺序不确定,不保证与添加顺序一致。

二、SortedList(排序列表)

1. 基本概念
  • 非泛型集合:存储键值对,且按键自动排序(升序)。

  • 双重索引:支持通过键(如 sortedList[10])或索引位置(如 sortedList.GetByIndex(0))访问。

  • 内存优化:内部使用数组实现,适合静态数据(插入 / 删除频繁时性能较差)。

2. 创建与初始化
// 创建空的 SortedList
SortedList sortedList = new SortedList();
​
// 创建并初始化
SortedList list = new SortedList() {
    { 10, "这是10" },
    { 6, "这是6" },
    { 5, "这是5" },
    { 3, "这是3" }
};
// 注意:键必须可比较(实现 IComparable 接口),否则会报错(如混合数值和字符类型)
3. 常用属性与方法
操作 代码示例 说明
添加键值对 list.Add(1, "这是1"); 添加键值对(键不存在时)。
通过键访问值 string value = (string)list[10]; 通过键获取值(返回 object,需强制类型转换)。
通过索引访问值 string value = (string)list.GetByIndex(0); 通过索引位置获取值(索引按升序排列)。
通过索引访问键 object key = list.GetKey(0); 获取指定索引位置的键。
修改值 list[10] = "新值"; 通过键修改对应的值。
删除键值对 list.Remove(10); 删除指定键对应的元素。
删除指定索引 list.RemoveAt(0); 删除指定索引位置的元素。
清空列表 list.Clear(); 移除所有键值对。
获取元素数量 int count = list.Count; 返回列表中键值对的数量。
获取所有键 ICollection keys = list.Keys; 返回所有键的集合(按键升序排列)。
获取所有值 ICollection values = list.Values; 返回所有值的集合(按对应键的升序排列)。
4. 遍历 SortedList
// 遍历所有键值对(按键升序)
foreach (DictionaryEntry entry in list) {
    Console.WriteLine($"Key: {entry.Key}, Value: {entry.Value}");
}
​
// 通过索引遍历
for (int i = 0; i < list.Count; i++) {
    Console.WriteLine($"Index: {i}, Key: {list.GetKey(i)}, Value: {list.GetByIndex(i)}");
}
5. 注意事项
  • 键的可比较性:键必须实现 IComparable 接口(如 intstring 等),否则会抛出异常。

  • 性能特点:插入 / 删除操作较慢(O (n)),但查找效率高(O (log n))。

  • 索引与键的区别:索引从 0 开始,按升序排列的键顺序分配;而键是用户自定义的。

三、Hashtable 与 SortedList 的对比

特性 Hashtable SortedList
排序 无序 按键升序排序
数据结构 哈希表(散列表) 数组(双重索引)
查找效率 O (1)(平均) O(log n)
插入 / 删除 O (1)(平均) O (n)(需移动元素)
内存占用 较高(需维护哈希表) 较低(仅数组)
键类型要求 需正确实现 GetHashCode() 需实现 IComparable 接口
线程安全 默认非线程安全 默认非线程安全
推荐场景 快速查找,无需排序 需按键排序,且插入 / 删除较少

四、代码补充建议

1. Hashtable 补充
// 线程安全的 Hashtable
Hashtable syncTable = Hashtable.Synchronized(new Hashtable());
​
// 安全添加(避免键已存在的异常)
if (!table.ContainsKey(123)) {
    table.Add(123, "123");
}
​
// 安全获取值(避免键不存在的异常)
object value;
if (table.ContainsKey(0)) {
    value = table[0];
}
2. SortedList 补充
// 使用泛型版本 SortedList(类型安全,无需装箱拆箱)
SortedList genericList = new SortedList {
    { 10, "这是10" },
    { 6, "这是6" }
};
​
// 检查键是否存在
if (genericList.ContainsKey(10)) {
    Console.WriteLine(genericList[10]);
}
​
// 添加或更新值
if (genericList.ContainsKey(10)) {
    genericList[10] = "更新的值";
} else {
    genericList.Add(10, "新值");
}

五、注意事项

  1. 泛型替代方案:推荐使用 Dictionary(替代 Hashtable)和 SortedList(替代非泛型 SortedList),以避免装箱拆箱。

  2. 性能权衡SortedList 在数据量大且插入 / 删除频繁时性能较差,可考虑使用 SortedDictionary(基于红黑树,插入 / 删除效率为 O (log n))。

  3. 空引用检查:访问集合元素前建议检查 ContainsKey 或使用 TryGetValu

你可能感兴趣的:(c#,哈希算法,开发语言)