代码已经经过初步测试,未来会有更多的类方上来,包括
Hashtable 存放非重复key的无序列表(.net标准类库,不需要重写)
HashArray 存放非重复key的有序列表
Bag 存放重复key的有序列表
Map 存放重复key的无序列表
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**/////////
using System;
using System.Collections;
![](/Images/OutliningIndicators/None.gif)
namespace deltav.Collections
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>可以有键值重复的无序列表</summary>
public class Map : IDictionary, IDisposable
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
Internal Data#region Internal Data
internal Hashtable m_InternalData;
int m_Count = 0;
internal int m_Version = 0;
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
Constructors#region Constructors
public Map()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
m_InternalData = new Hashtable();
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
Internal Functions#region Internal Functions
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 确保 key 对应的容器存在,并返回该容器
/// </summary>
/// <param name="key">key</param>
/// <returns>key 对应的容器</returns>
protected ArrayList MakeKeyExist(object key)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (key == null)
throw new ArgumentNullException("key");
if (!m_InternalData.ContainsKey(key))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
ArrayList containor = new ArrayList();
m_InternalData.Add(key, containor);
++m_Version;
return containor;
}
else
return (ArrayList)m_InternalData[key];
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 清理部分数据内容
/// </summary>
protected void ParticalClear()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
foreach (DictionaryEntry ent in this.m_InternalData)
((ArrayList)ent.Value).Clear();
m_Count = 0;
++m_Version;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 取得实际数据
/// </summary>
protected int GetCount()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
int count = 0;
foreach (DictionaryEntry ent in this.m_InternalData)
count += ((ArrayList)ent.Value).Count;
![](/Images/OutliningIndicators/InBlock.gif)
return count;
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 计算key对应的对象个数
/// </summary>
/// <param name="key">key</param>
/// <returns>对象个数</returns>
public int CountKey(object key)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (this.m_InternalData.ContainsKey(key))
return ((ArrayList)this.m_InternalData[key]).Count;
else
return 0;
}
![](/Images/OutliningIndicators/InBlock.gif)
public void RemoveAt(object key, int index)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (m_InternalData.ContainsKey(key))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
MakeKeyExist(key).RemoveAt(index);
--m_Count;
++m_Version;
}
else
throw new ArgumentOutOfRangeException("index");
}
![](/Images/OutliningIndicators/InBlock.gif)
public object this[object key, int index]
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (this.m_InternalData.ContainsKey(key))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return MakeKeyExist(key)[index];
}
else
throw new ArgumentOutOfRangeException("index");
}
set
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
MakeKeyExist(key)[index] = value;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
IEnumerator GetEnumerator(object key)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (this.m_InternalData.ContainsKey(key))
return MakeKeyExist(key).GetEnumerator();
else
return null;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
Internal Enumerator#region Internal Enumerator
![](/Images/OutliningIndicators/InBlock.gif)
private class MapEnumerator : IDictionaryEnumerator
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Map m_Owner;
IDictionaryEnumerator master; // master == null 尚未开始
IEnumerator slave;
int version;
object current; // current == null 已经结束
![](/Images/OutliningIndicators/InBlock.gif)
public MapEnumerator(Map owner)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
m_Owner = owner;
master = null;
slave = null;
current = null;
version = owner.m_Version;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
IDictionaryEnumerator Members#region IDictionaryEnumerator Members
public DictionaryEntry Entry
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (master == null)
throw new InvalidOperationException("迭代尚未开始");
if (current == null)
throw new InvalidOperationException("迭代已经结束");
if (version != m_Owner.m_Version)
throw new InvalidOperationException("迭代期间数据已经被改变");
return (DictionaryEntry)current;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public object Key
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return Entry.Key; }
}
![](/Images/OutliningIndicators/InBlock.gif)
public object Value
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return Entry.Value; }
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
IEnumerator Members#region IEnumerator Members
public object Current
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return Entry; }
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
public bool MoveNext()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (version != m_Owner.m_Version)
throw new InvalidOperationException("迭代期间数据已经被改变");
![](/Images/OutliningIndicators/InBlock.gif)
bool ok = true;
if (this.master == null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
this.master = this.m_Owner.m_InternalData.GetEnumerator();
ok = this.master.MoveNext();
if( !ok ) return false;
}
![](/Images/OutliningIndicators/InBlock.gif)
DictionaryEntry master_current;
while (ok)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
master_current = (DictionaryEntry)master.Current;
if (this.slave == null)
slave = m_Owner.GetEnumerator(master_current.Key);
if (slave != null && slave.MoveNext())
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
current = new DictionaryEntry(master_current.Key, slave.Current);
return true;
}
ok = this.master.MoveNext();
slave = null;
}
current = null;
return false;
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Reset()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
master = null;
slave = null;
current = null;
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
}
![](/Images/OutliningIndicators/InBlock.gif)
private class MapValueCollection : ICollection
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Map m_Owner;
int m_Version;
![](/Images/OutliningIndicators/InBlock.gif)
public MapValueCollection(Map owner)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
m_Owner = owner;
m_Version = owner.m_Version;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
ICollection Members#region ICollection Members
![](/Images/OutliningIndicators/InBlock.gif)
public void CopyTo(Array array, int index)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
foreach (DictionaryEntry ent in this.m_Owner.m_InternalData)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
ArrayList a = (ArrayList)ent.Value;
if (a != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
a.CopyTo(array, index);
index += a.Count;
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public int Count
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return m_Owner.Count; }
}
![](/Images/OutliningIndicators/InBlock.gif)
public bool IsSynchronized
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return m_Owner.IsSynchronized; }
}
![](/Images/OutliningIndicators/InBlock.gif)
public object SyncRoot
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return m_Owner.SyncRoot; }
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
IEnumerable Members#region IEnumerable Members
![](/Images/OutliningIndicators/InBlock.gif)
public IEnumerator GetEnumerator()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return new MapValueEnumerator(this.m_Owner);
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
}
![](/Images/OutliningIndicators/InBlock.gif)
private class MapValueEnumerator : IEnumerator
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Map m_Owner;
IEnumerator iter;
int version;
object current;
![](/Images/OutliningIndicators/InBlock.gif)
public MapValueEnumerator(Map owner)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
m_Owner = owner;
version = m_Owner.m_Version;
iter = null;
current = null; // 表示尚未开始:和其他枚举的标志不一样,正好相反
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
IEnumerator Members#region IEnumerator Members
public object Current
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (iter == null)
throw new InvalidOperationException("迭代尚未开始");
if (current == m_Owner)
throw new InvalidOperationException("迭代已经结束");
if (version != m_Owner.m_Version)
throw new InvalidOperationException("迭代期间数据已经被改变");
return current;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public bool MoveNext()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (version != m_Owner.m_Version)
throw new InvalidOperationException("迭代期间数据已经被改变");
if (current == m_Owner)
throw new InvalidOperationException("迭代已经结束");
![](/Images/OutliningIndicators/InBlock.gif)
if (iter == null)
iter = m_Owner.GetEnumerator();
if (iter.MoveNext())
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
current = ((DictionaryEntry)iter.Current).Value;
return true;
}
else
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
current = m_Owner; // 表示结束
return false;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Reset()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
iter = null;
current = m_Owner;
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
IDictionary Members#region IDictionary Members
![](/Images/OutliningIndicators/InBlock.gif)
public void Add(object key, object value)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
MakeKeyExist(key).Add(value);
++m_Count;
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Clear()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
ParticalClear();
}
![](/Images/OutliningIndicators/InBlock.gif)
public bool Contains(object key)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return this.m_InternalData.ContainsKey(key);
}
![](/Images/OutliningIndicators/InBlock.gif)
public IDictionaryEnumerator GetEnumerator()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return new MapEnumerator(this);
}
![](/Images/OutliningIndicators/InBlock.gif)
public bool IsFixedSize
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return this.m_InternalData.IsFixedSize; }
}
![](/Images/OutliningIndicators/InBlock.gif)
public bool IsReadOnly
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return this.m_InternalData.IsReadOnly; }
}
![](/Images/OutliningIndicators/InBlock.gif)
public ICollection Keys
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return this.m_InternalData.Keys; }
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Remove(object key)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (this.m_InternalData.ContainsKey(key))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
ArrayList containor = MakeKeyExist(key);
m_Count -= containor.Count;
++m_Version;
containor.Clear();
m_InternalData.Remove(key);
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public ICollection Values
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return new MapValueCollection(this); }
}
![](/Images/OutliningIndicators/InBlock.gif)
public object this[object key]
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (this.m_InternalData.ContainsKey(key))
return this.MakeKeyExist(key)[0];
else
return null;
}
![](/Images/OutliningIndicators/InBlock.gif)
set
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (this.m_InternalData.ContainsKey(key))
this.MakeKeyExist(key)[0] = value;
else
this.MakeKeyExist(key).Add(value);
++m_Version;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
ICollection Members#region ICollection Members
![](/Images/OutliningIndicators/InBlock.gif)
public void CopyTo(Array array, int index)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
int i;
ArrayList list;
foreach (DictionaryEntry ent in this.m_InternalData)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
list = (ArrayList)ent.Value;
for (i = 0; i < list.Count; ++i)
array.SetValue(new DictionaryEntry(ent.Key, list[i]), index++);
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public int Count
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
#if DEBUG
System.Diagnostics.Debug.Assert(GetCount() == m_Count);
#endif
return m_Count;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public bool IsSynchronized
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return this.m_InternalData.IsSynchronized; }
}
![](/Images/OutliningIndicators/InBlock.gif)
public object SyncRoot
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return this.m_InternalData.SyncRoot; }
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
IEnumerable Members#region IEnumerable Members
![](/Images/OutliningIndicators/InBlock.gif)
IEnumerator IEnumerable.GetEnumerator()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return new MapEnumerator(this);
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
IDisposable Members#region IDisposable Members
![](/Images/OutliningIndicators/InBlock.gif)
public void Dispose()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
ParticalClear();
this.m_InternalData.Clear();
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
}