在上面介绍过栈(Stack)的存储结构,接下来介绍另一种存储结构字典(Dictionary)。 字典(Dictionary)里面的每一个元素都是一个键值对(由二个元素组成:键和值) 键必须是唯一的,而值不需要唯一的,键和值都可以是任何类型。字典(Dictionary)是常用于查找和排序的列表。

接下来看一下Dictionary的部分方法和类的底层实现代码:

1.Add:将指定的键和值添加到字典中。

public void Add(TKey key, TValue value) {
Insert(key, value, true);
}
        private void Insert(TKey key, TValue value, bool add) {

            if( key == null ) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
} if (buckets == null) Initialize();
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
int targetBucket = hashCode % buckets.Length; #if FEATURE_RANDOMIZED_STRING_HASHING
int collisionCount = ;
#endif for (int i = buckets[targetBucket]; i >= ; i = entries[i].next) {
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) {
if (add) {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
}
entries[i].value = value;
version++;
return;
} #if FEATURE_RANDOMIZED_STRING_HASHING
collisionCount++;
#endif
}
int index;
if (freeCount > ) {
index = freeList;
freeList = entries[index].next;
freeCount--;
}
else {
if (count == entries.Length)
{
Resize();
targetBucket = hashCode % buckets.Length;
}
index = count;
count++;
} entries[index].hashCode = hashCode;
entries[index].next = buckets[targetBucket];
entries[index].key = key;
entries[index].value = value;
buckets[targetBucket] = index;
version++; #if FEATURE_RANDOMIZED_STRING_HASHING
if(collisionCount > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(comparer))
{
comparer = (IEqualityComparer<TKey>) HashHelpers.GetRandomizedEqualityComparer(comparer);
Resize(entries.Length, true);
}
#endif }

2.Clear():从 Dictionary<TKey, TValue> 中移除所有的键和值。

        public void Clear() {
if (count > ) {
for (int i = ; i < buckets.Length; i++) buckets[i] = -;
Array.Clear(entries, , count);
freeList = -;
count = ;
freeCount = ;
version++;
}
}

3.Remove():从 Dictionary<TKey, TValue> 中移除所指定的键的值。

        public bool Remove(TKey key) {
if(key == null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
} if (buckets != null) {
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
int bucket = hashCode % buckets.Length;
int last = -;
for (int i = buckets[bucket]; i >= ; last = i, i = entries[i].next) {
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) {
if (last < ) {
buckets[bucket] = entries[i].next;
}
else {
entries[last].next = entries[i].next;
}
entries[i].hashCode = -;
entries[i].next = freeList;
entries[i].key = default(TKey);
entries[i].value = default(TValue);
freeList = i;
freeCount++;
version++;
return true;
}
}
}
return false;
}

4.GetEnumerator():返回循环访问 Dictionary<TKey, TValue> 的枚举器。

public Enumerator GetEnumerator() {
return new Enumerator(this, Enumerator.KeyValuePair);
}
 [Serializable]
public struct Enumerator: IEnumerator<KeyValuePair<TKey,TValue>>,
IDictionaryEnumerator
{
private Dictionary<TKey,TValue> dictionary;
private int version;
private int index;
private KeyValuePair<TKey,TValue> current;
private int getEnumeratorRetType; // What should Enumerator.Current return? internal const int DictEntry = ;
internal const int KeyValuePair = ; internal Enumerator(Dictionary<TKey,TValue> dictionary, int getEnumeratorRetType) {
this.dictionary = dictionary;
version = dictionary.version;
index = ;
this.getEnumeratorRetType = getEnumeratorRetType;
current = new KeyValuePair<TKey, TValue>();
} public bool MoveNext() {
if (version != dictionary.version) {
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
} // Use unsigned comparison since we set index to dictionary.count+1 when the enumeration ends.
// dictionary.count+1 could be negative if dictionary.count is Int32.MaxValue
while ((uint)index < (uint)dictionary.count) {
if (dictionary.entries[index].hashCode >= ) {
current = new KeyValuePair<TKey, TValue>(dictionary.entries[index].key, dictionary.entries[index].value);
index++;
return true;
}
index++;
} index = dictionary.count + ;
current = new KeyValuePair<TKey, TValue>();
return false;
} public KeyValuePair<TKey,TValue> Current {
get { return current; }
} public void Dispose() {
} object IEnumerator.Current {
get {
if( index == || (index == dictionary.count + )) {
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
} if (getEnumeratorRetType == DictEntry) {
return new System.Collections.DictionaryEntry(current.Key, current.Value);
} else {
return new KeyValuePair<TKey, TValue>(current.Key, current.Value);
}
}
} void IEnumerator.Reset() {
if (version != dictionary.version) {
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
} index = ;
current = new KeyValuePair<TKey, TValue>();
} DictionaryEntry IDictionaryEnumerator.Entry {
get {
if( index == || (index == dictionary.count + )) {
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
} return new DictionaryEntry(current.Key, current.Value);
}
} object IDictionaryEnumerator.Key {
get {
if( index == || (index == dictionary.count + )) {
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
} return current.Key;
}
} object IDictionaryEnumerator.Value {
get {
if( index == || (index == dictionary.count + )) {
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
} return current.Value;
}
}
}

上面主要是对字典(Dictionary)的一些常用方法进行一个简单的说明。接下来主要阐述如何创建安全的字典(Dictionary)存储结构。有关线程安全的部分,在这里就不再赘述了。

    /// <summary>
/// 线程安全通用字典
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
public class TDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
/// <summary>
/// 锁定字典
/// </summary>
private readonly ReaderWriterLockSlim _lockDictionary = new ReaderWriterLockSlim(); /// <summary>
///基本字典
/// </summary>
private readonly Dictionary<TKey, TValue> _mDictionary; // Variables
/// <summary>
/// 初始化字典对象
/// </summary>
public TDictionary()
{
_mDictionary = new Dictionary<TKey, TValue>();
} /// <summary>
/// 初始化字典对象
/// </summary>
/// <param name="capacity">字典的初始容量</param>
public TDictionary(int capacity)
{
_mDictionary = new Dictionary<TKey, TValue>(capacity);
} /// <summary>
///初始化字典对象
/// </summary>
/// <param name="comparer">比较器在比较键时使用</param>
public TDictionary(IEqualityComparer<TKey> comparer)
{
_mDictionary = new Dictionary<TKey, TValue>(comparer);
} /// <summary>
/// 初始化字典对象
/// </summary>
/// <param name="dictionary">其键和值被复制到此对象的字典</param>
public TDictionary(IDictionary<TKey, TValue> dictionary)
{
_mDictionary = new Dictionary<TKey, TValue>(dictionary);
} /// <summary>
///初始化字典对象
/// </summary>
/// <param name="capacity">字典的初始容量</param>
/// <param name="comparer">比较器在比较键时使用</param>
public TDictionary(int capacity, IEqualityComparer<TKey> comparer)
{
_mDictionary = new Dictionary<TKey, TValue>(capacity, comparer);
} /// <summary>
/// 初始化字典对象
/// </summary>
/// <param name="dictionary">其键和值被复制到此对象的字典</param>
/// <param name="comparer">比较器在比较键时使用</param>
public TDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
{
_mDictionary = new Dictionary<TKey, TValue>(dictionary, comparer);
} public TValue GetValueAddIfNotExist(TKey key, Func<TValue> func)
{
return _lockDictionary.PerformUsingUpgradeableReadLock(() =>
{
TValue rVal; // 如果我们有值,得到它并退出
if (_mDictionary.TryGetValue(key, out rVal))
return rVal; // 没有找到,所以做函数得到的值
_lockDictionary.PerformUsingWriteLock(() =>
{
rVal = func.Invoke(); // 添加到字典
_mDictionary.Add(key, rVal); return rVal;
}); return rVal;
});
} /// <summary>
/// 将项目添加到字典
/// </summary>
/// <param name="key">添加的关键</param>
/// <param name="value">要添加的值</param>
public void Add(TKey key, TValue value)
{
_lockDictionary.PerformUsingWriteLock(() => _mDictionary.Add(key, value));
} /// <summary>
///将项目添加到字典
/// </summary>
/// <param name="item">要添加的键/值</param>
public void Add(KeyValuePair<TKey, TValue> item)
{
var key = item.Key;
var value = item.Value;
_lockDictionary.PerformUsingWriteLock(() => _mDictionary.Add(key, value));
} /// <summary>
/// 如果值不存在,则添加该值。 返回如果值已添加,则为true
/// </summary>
/// <param name="key">检查的关键,添加</param>
/// <param name="value">如果键不存在,则添加的值</param>
public bool AddIfNotExists(TKey key, TValue value)
{
bool rVal = false; _lockDictionary.PerformUsingWriteLock(() =>
{
// 如果不存在,则添加它
if (!_mDictionary.ContainsKey(key))
{
// 添加该值并设置标志
_mDictionary.Add(key, value);
rVal = true;
}
}); return rVal;
} /// <summary>
/// 如果键不存在,则添加值列表。
/// </summary>
/// <param name="keys">要检查的键,添加</param>
/// <param name="defaultValue">如果键不存在,则添加的值</param>
public void AddIfNotExists(IEnumerable<TKey> keys, TValue defaultValue)
{
_lockDictionary.PerformUsingWriteLock(() =>
{
foreach (TKey key in keys)
{
// 如果不存在,则添加它
if (!_mDictionary.ContainsKey(key))
_mDictionary.Add(key, defaultValue);
}
});
} public bool AddIfNotExistsElseUpdate(TKey key, TValue value)
{
var rVal = false; _lockDictionary.PerformUsingWriteLock(() =>
{
// 如果不存在,则添加它
if (!_mDictionary.ContainsKey(key))
{
// 添加该值并设置标志
_mDictionary.Add(key, value);
rVal = true;
}
else
_mDictionary[key] = value;
}); return rVal;
} /// <summary>
/// 如果键存在,则更新键的值。
/// </summary>
/// <param name="key"></param>
/// <param name="newValue"></param>
public bool UpdateValueIfKeyExists(TKey key, TValue newValue)
{
bool rVal = false; _lockDictionary.PerformUsingWriteLock(() =>
{
// 如果我们有密钥,然后更新它
if (!_mDictionary.ContainsKey(key)) return;
_mDictionary[key] = newValue;
rVal = true;
}); return rVal;
} /// <summary>
/// 如果键值对存在于字典中,则返回true
/// </summary>
/// <param name="item">键值对查找</param>
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return _lockDictionary.PerformUsingReadLock(() => ((_mDictionary.ContainsKey(item.Key)) &&
(_mDictionary.ContainsValue(item.Value))));
} public bool ContainsKey(TKey key)
{
return _lockDictionary.PerformUsingReadLock(() => _mDictionary.ContainsKey(key));
} /// <summary>
/// 如果字典包含此值,则返回true
/// </summary>
/// <param name="value">找到的值</param>
public bool ContainsValue(TValue value)
{
return _lockDictionary.PerformUsingReadLock(() => _mDictionary.ContainsValue(value));
} public ICollection<TKey> Keys
{
get { return _lockDictionary.PerformUsingReadLock(() => _mDictionary.Keys); }
} public bool Remove(TKey key)
{
return _lockDictionary.PerformUsingWriteLock(() => (!_mDictionary.ContainsKey(key)) || _mDictionary.Remove(key));
} public bool Remove(KeyValuePair<TKey, TValue> item)
{
return _lockDictionary.PerformUsingWriteLock(() =>
{
// 如果键不存在则跳过
TValue tempVal;
if (!_mDictionary.TryGetValue(item.Key, out tempVal))
return false; //如果值不匹配,请跳过
return tempVal.Equals(item.Value) && _mDictionary.Remove(item.Key);
});
} /// <summary>
/// 从字典中删除与模式匹配的项
/// </summary>
/// <param name="predKey">基于键的可选表达式</param>
/// <param name="predValue">基于值的选项表达式</param>
public bool Remove(Predicate<TKey> predKey, Predicate<TValue> predValue)
{
return _lockDictionary.PerformUsingWriteLock(() =>
{
// 如果没有键退出
if (_mDictionary.Keys.Count == )
return true; //保存要删除的项目列表
var deleteList = new List<TKey>(); // 过程密钥
foreach (var key in _mDictionary.Keys)
{
var isMatch = false; if (predKey != null)
isMatch = (predKey(key)); // 如果此项目的值匹配,请添加它
if ((!isMatch) && (predValue != null) && (predValue(_mDictionary[key])))
isMatch = true; // 如果我们有匹配,添加到列表
if (isMatch)
deleteList.Add(key);
} // 从列表中删除所有项目
foreach (var item in deleteList)
_mDictionary.Remove(item); return true;
});
} public bool TryGetValue(TKey key, out TValue value)
{
_lockDictionary.EnterReadLock();
try
{
return _mDictionary.TryGetValue(key, out value);
}
finally
{
_lockDictionary.ExitReadLock();
} } public ICollection<TValue> Values
{
get { return _lockDictionary.PerformUsingReadLock(() => _mDictionary.Values); }
} public TValue this[TKey key]
{
get { return _lockDictionary.PerformUsingReadLock(() => _mDictionary[key]); } set { _lockDictionary.PerformUsingWriteLock(() => _mDictionary[key] = value); }
} /// <summary>
/// 清除字典
/// </summary>
public void Clear()
{
_lockDictionary.PerformUsingWriteLock(() => _mDictionary.Clear());
} public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
_lockDictionary.PerformUsingReadLock(() => _mDictionary.ToArray().CopyTo(array, arrayIndex));
} /// <summary>
/// 返回字典中的项目数
/// </summary>
public int Count
{
get { return _lockDictionary.PerformUsingReadLock(() => _mDictionary.Count); }
} public bool IsReadOnly
{
get { return false; }
} public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
Dictionary<TKey, TValue> localDict = null; _lockDictionary.PerformUsingReadLock(() => localDict = new Dictionary<TKey, TValue>(_mDictionary)); return ((IEnumerable<KeyValuePair<TKey, TValue>>)localDict).GetEnumerator();
} System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
Dictionary<TKey, TValue> localDict = null; _lockDictionary.PerformUsingReadLock(() => localDict = new Dictionary<TKey, TValue>(_mDictionary)); return localDict.GetEnumerator();
} }

以上创建安全的字典方法中,主要对字典的一些方法和属性进行重写操作,对某些方法进行锁设置。

C#创建安全的字典(Dictionary)存储结构的更多相关文章

  1. C#创建安全的栈(Stack)存储结构

    在C#中,用于存储的结构较多,如:DataTable,DataSet,List,Dictionary,Stack等结构,各种结构采用的存储的方式存在差异,效率也必然各有优缺点.现在介绍一种后进先出的数 ...

  2. 你真的了解字典(Dictionary)吗? C# Memory Cache 踩坑记录 .net 泛型 结构化CSS设计思维 WinForm POST上传与后台接收 高效实用的.NET开源项目 .net 笔试面试总结(3) .net 笔试面试总结(2) 依赖注入 C# RSA 加密 C#与Java AES 加密解密

    你真的了解字典(Dictionary)吗?   从一道亲身经历的面试题说起 半年前,我参加我现在所在公司的面试,面试官给了一道题,说有一个Y形的链表,知道起始节点,找出交叉节点.为了便于描述,我把上面 ...

  3. Hashtable数据存储结构-遍历规则,Hash类型的复杂度为啥都是O(1)-源码分析

    Hashtable 是一个很常见的数据结构类型,前段时间阿里的面试官说只要搞懂了HashTable,hashMap,HashSet,treeMap,treeSet这几个数据结构,阿里的数据结构面试没问 ...

  4. 索引器、哈希表Hashtabl、字典Dictionary(转)

    一.索引器 索引器类似于属性,不同之处在于它们的get访问器采用参数.要声明类或结构上的索引器,使用this关键字. 示例:   索引器示例代码 /// <summary> /// 存储星 ...

  5. Python 字典(Dictionary)操作详解

    Python 字典(Dictionary)的详细操作方法. Python字典是另一种可变容器模型,且可存储任意类型对象,如字符串.数字.元组等其他容器模型. 一.创建字典 字典由键和对应值成对组成.字 ...

  6. 从NSM到Parquet:存储结构的衍化

    http://blog.csdn.net/dc_726/article/details/41777661 为了优化MapReduce及MR之前的各种工具的性能,在Hadoop内建的数据存储格式外,又涌 ...

  7. Python 3语法小记(四)字典 dictionary

    字典是Python里面一种无序存储结构,存储的是键值对 key - value.关键字应该为不可变类型,如字符串.整数.包含不可变对象的元组. 字典的创建很简单,用 d = {key1 : value ...

  8. Redis之(二)数据类型及存储结构

    Redis支持五中数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及zset(sortedset:有序集合). Redis定义了丰富的原语命令,可以直接与Redis ...

  9. 你真的了解字典(Dictionary)吗?

    从一道亲身经历的面试题说起 半年前,我参加我现在所在公司的面试,面试官给了一道题,说有一个Y形的链表,知道起始节点,找出交叉节点. 为了便于描述,我把上面的那条线路称为线路1,下面的称为线路2. 思路 ...

随机推荐

  1. Jtable 表格按多列排序(支持中文汉字排序)

    这两天公司让做一个Jtable表格的排序,首先按A列排序,在A列相等时按B列排序,B列相等时按C列排序,ABC三列可以任意指定,最多分三列,这样的一个需求.由于我是大神,所以必须做了出来.ok,不自恋 ...

  2. 用Fmx调用Bass.dll

    先上图 帮亲戚做个小软件,选用FMX,因为画面不会像vcl那样在图片多的时候闪烁.还能添加动画 但是MediaPlayer播放音乐视频真是不给力,视频没想到好办法.音频方面想到之前万一的Bass.ll ...

  3. 多线程导出大规模excel文件

    文章有点水,和前几篇没有太大区别,但是单线程处理大文件导出会非常耗时间,用到多线程才能更加合理的利用资源.大文件也可能会超出excel工作表范围.这里也有相应处理 参考:用DataGridView导入 ...

  4. 基于OWin的Web服务器Katana发布版本3

    当 ASP.NET 首次在 2002 年发布时,时代有所不同. 那时,Internet 仍处于起步阶段,大约有 5.69 亿用户,每个用户平均每天访问 Internet 的时间为 46 分钟,大约有 ...

  5. 【BOOM】一款有趣的Javascript动画效果

    实践出真知,有的时候看到一些有趣的现象就想着用自己所学的知识复现一下.    boomJS 缘起 前几天在 github 上看到同事的一个这样的小项目,在 IOS 上实现了这样一个小动画效果,看上去蛮 ...

  6. Net作业调度(一) -Quartz.Net入门

    背景 很多时候,项目需要在不同时刻,执行一个或很多个不同的作业. Windows执行计划这时并不能很好的满足需求了,迫切需要一个更为强大,方便管理,集群部署的作业调度框架. 介绍 Quartz一个开源 ...

  7. VBA批量查找和复制文件

    Function findAndCopy(srcFile As String, destFile As String, cmdFile As String) Dim WSH As Object, wE ...

  8. ABP(现代ASP.NET样板开发框架)主题线下交流会(上海)开始报名了!

    点这里进入ABP系列文章总目录 ABP主题线下交流会(上海)开始报名了 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称.它是采用最佳实践和流行技术 ...

  9. xamarin UWP证书问题汇总

    打算开发一个软件使用rsa加密的东西,所以有用到数字证书这块,最近遇到些问题, 问题一:使用如下代码添加数字证书后,在证书管理器的当前用户和本地计算机下都找不到这张证书. using (X509Sto ...

  10. iOS-Xcode使用技巧

    一.快捷键的使用 经常用到的快捷键如下: 新建 shift + cmd + n     新建项目 cmd + n             新建文件 视图 option + cmd + 回车 打开助理编 ...