在上面介绍过栈(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. C++中的显式类型转化

    类型转化也许大家并不陌生,int i; float j; j = (float)i; i = (int)j; 像这样的显式转化其实很常见,强制类型转换可能会丢失部分数据,所以如果不加(int)做强制转 ...

  2. 执行CSRF令牌所有形式使用POST方法

    从而在并未授权的情况下执行在权限保护之下的操作,有很大的危害性. php CSRF Guardfunction csrfguard_generate_token($unique_form_name){ ...

  3. CSS基础篇之选择符

    关系选择符 E F 包含选择符(Descendant combinator) CSS1 选择所有被E元素包含的F元素. <html> <head> <meta chars ...

  4. 一小时包教会 —— webpack 入门指南

    什么是 webpack? webpack是近期最火的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX).coffee.样式(含less/sass).图片等都作为模块来使用和处理. 我们可以 ...

  5. HappyAA服务器部署笔记2(nginx的静态资源缓存配置)

    我近期对服务器进行了少量改进,虽然之前使用了nginx反向代理之后性能有所提高,但仍然不够,需要使用缓存来大幅度提高静态资源的访问速度. 服务器上的静态资源主要有这些:png, jpg, svg, j ...

  6. [开源]C#二维码生成解析工具,可添加自定义Logo

    二维码又称 QR Code,QR 全称 Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的 Bar Code 条形码能存更多的信息,也能表示更多的数据类型:比如:字 ...

  7. linux 使用fdisk分区扩容

    标签:fdisk分区 概述 我们管理的服务器可能会随着业务量的不断增长造成磁盘空间不足的情况,在这个时候我们就需要增加磁盘空间,本章主要介绍如何使用fdisk分区工具创建磁盘分区和挂载分区,介绍两种情 ...

  8. 在.NET中使用管道将输出流转换为输入流

    最近在写一段代码,将本地文件压缩加密后发送到服务器,发送到服务器的类用一个输入流作为参数获取要上传的数据,而压缩类和加密类都是输出流. 如何将输出流转换为输入流,最直观的方法是缓存输出流的全部内容到内 ...

  9. Unbroken(坚不可摧)——Mateusz M

    Unbroken(坚不可摧)——Mateusz M YouTube励志红人账号Mateusz M 的作品,短片由几位演讲家Les Brown.Eric Thomas.Steve Jobs.Louis ...

  10. 分享自己写的JS版日期格式化和解析工具类,绝对好用!

    前言 本来想模仿Java里面的SimpleDateFormat()对象的,但是感觉这样用起来不方便,所以还是直接写成单独的方法算了. 原文链接 日期格式化 使用说明 formatDate(date, ...