Hashtable、Dictionary、HashSet、List的区别
Hashtable、Dictionary
Hashtable、Dictionary:使用方式类似,都是存储键值对,推荐Dictionary
Hashtable
Hashtable存储键值对,key、value都是object类型
直接实例化的 Hashtable(如 new Hashtable())不是线程安全的。多线程并发读写可能导致数据损坏或异常
线程安全实现方式:Hashtable类中有个类SyncHashtable ,封装Hashtable实例,SyncHashtable就是一个装饰器,内部使用lock保证线程安全
private static Hashtable ht1 = Hashtable.Synchronized ( new Hashtable () );//Hashtable.Synchronized()返回Hashtable的同步包装(线程安全)
复合操作仍需外部锁:例如“检查是否存在再插入”需手动加锁
lock (syncTable.SyncRoot) {
if (!syncTable.ContainsKey("key"))
syncTable.Add("key", "value");
}
现代替代方案(推荐)ConcurrentDictionary<TKey, TValue>
细粒度锁:更高并发性能。
原子性复合操作:如 GetOrAdd、AddOrUpdate
var concurrentDict = new ConcurrentDictionary<string, string>();
concurrentDict.TryAdd("key", "value");
Dictionary
是泛型,不需要装拆箱
Dictionary不是线程安全的,如果多线程环境可以使用ConcurrentDictionary
List、HashSet
List
- 基于动态数组实现,元素按插入顺序存储。
- 允许重复元素,支持索引访问(如list[0])。
- 查找特定元素需遍历整个列表,时间复杂度为O(n)。
HashSet
- 基于哈希表实现,元素通过哈希码存储。
- 不允许重复元素(自动去重),且不保证顺序。
- 查找、插入、删除操作的平均时间复杂度为O(1)(哈希冲突时可能退化到O(n))。
适用场景
使用List
- 需要保留元素插入顺序(如日志记录)。
- 允许重复元素(如购物车商品列表)。
- 频繁通过索引访问(如list[i])。
使用HashSet当: - 需要快速判断元素是否存在(如黑名单检查)。
- 要求元素唯一性(如用户ID集合)。
- 频繁执行集合操作(如并集、交集)。
// List<T>示例:允许重复,有序
List<int> list = new List<int> { 1, 2, 2, 3 };
Console.WriteLine(string.Join(", ", list)); // 输出: 1, 2, 2, 3
// HashSet<T>示例:自动去重,无序
HashSet<int> set = new HashSet<int> { 1, 2, 2, 3 };
Console.WriteLine(string.Join(", ", set)); // 输出可能为: 1, 2, 3(顺序不确定)
选择List<T>还是HashSet<T>取决于是否需要顺序、重复元素及性能优先级。List<T>适合顺序敏感场景,而HashSet<T>适合高效查找和去重。

浙公网安备 33010602011771号