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>

​细粒度锁​:更高并发性能。
​原子性复合操作​:如 GetOrAddAddOrUpdate

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>适合高效查找和去重。

posted @ 2020-06-14 17:59  .Neterr  阅读(496)  评论(0)    收藏  举报