using System;
using System.Collections;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Security;
using System.Collections.Generic;
namespace Thousandto.Core.Base
{
///
/// 在.net2.0环境下提供HashSet(Of T)类型的模拟实现
///
/// 集合中的元素类型
public class HashSet : ICollection, IEnumerable, IEnumerable, ISerializable, IDeserializationCallback
{
private readonly Dictionary dict;
#region constructors
///
/// Initializes a new instance of the System.Collections.Generic.HashSet class
/// that is empty and uses the default equality comparer for the set type.
///
public HashSet()
{
this.dict = new Dictionary();
}
///
/// Initializes a new instance of the System.Collections.Generic.HashSet class
/// that uses the default equality comparer for the set type, contains elements
/// copied from the specified collection, and has sufficient capacity to accommodate
/// the number of elements copied.
///
/// The collection whose elements are copied to the new set.
/// collection is null.
public HashSet(IEnumerable collection)
{
if (collection == null)
throw new ArgumentNullException("collection");
this.dict = new Dictionary();
foreach (T item in collection)
this.dict[item] = null;
}
///
/// Initializes a new instance of the System.Collections.Generic.HashSet class
/// that is empty and uses the specified equality comparer for the set type.
///
///
/// The System.Collections.Generic.IEqualityComparer implementation to use
/// when comparing values in the set, or null to use the default System.Collections.Generic.EqualityComparer
/// implementation for the set type.
///
public HashSet(IEqualityComparer comparer)
{
this.dict = new Dictionary(comparer);
}
///
/// Initializes a new instance of the System.Collections.Generic.HashSet class
/// that uses the specified equality comparer for the set type, contains elements
/// copied from the specified collection, and has sufficient capacity to accommodate
/// the number of elements copied.
///
/// The collection whose elements are copied to the new set.
///
/// The System.Collections.Generic.IEqualityComparer implementation to use
/// when comparing values in the set, or null to use the default System.Collections.Generic.EqualityComparer
/// implementation for the set type.
///
/// collection is null.
public HashSet(IEnumerable collection, IEqualityComparer comparer)
{
if (collection == null)
throw new ArgumentNullException("collection");
this.dict = new Dictionary(comparer);
foreach (T item in collection)
this.dict[item] = null;
}
#endregion
#region properties
///
/// Gets the System.Collections.Generic.IEqualityComparer object that is used
/// to determine equality for the values in the set.
///
public IEqualityComparer Comparer { get { return this.dict.Comparer; } }
///
/// Gets the number of elements that are contained in a set.
///
public int Count { get { return this.dict.Count; } }
#endregion
#region methods
///
/// Adds the specified element to a set.
///
/// The element to add to the set.
///
/// true if the element is added to the System.Collections.Generic.HashSet object;
/// false if the element is already present.
///
public bool Add(T item)
{
if (this.dict.ContainsKey(item))
{
return false;
}
else
{
this.dict[item] = null;
return true;
}
}
///
/// Removes all elements from a System.Collections.Generic.HashSet object.
///
public void Clear()
{
this.dict.Clear();
}
///
/// Determines whether a System.Collections.Generic.HashSet object contains the specified element.
///
/// The element to locate in the System.Collections.Generic.HashSet object.
/// true if the System.Collections.Generic.HashSet object contains the specified element; otherwise, false.
public bool Contains(T item)
{
return this.dict.ContainsKey(item);
}
///
/// Copies the elements of a System.Collections.Generic.HashSet object to an array.
///
///
/// The one-dimensional array that is the destination of the elements copied
/// from the System.Collections.Generic.HashSet object. The array must have
/// zero-based indexing.
///
/// array is null.
public void CopyTo(T[] array)
{
if (array == null)
throw new ArgumentNullException("array");
this.dict.Keys.CopyTo(array, 0);
}
///
/// Copies the elements of a System.Collections.Generic.HashSet object to an array, starting at the specified array index.
///
///
/// The one-dimensional array that is the destination of the elements copied
/// from the System.Collections.Generic.HashSet object. The array must have
/// zero-based indexing.
///
/// The zero-based index in array at which copying begins.
/// array is null.
/// arrayIndex is less than 0.
/// arrayIndex is greater than the length of the destination array. -or- count is larger than the size of the destination array.
public void CopyTo(T[] array, int arrayIndex)
{
if (array == null)
throw new ArgumentNullException("array");
if (arrayIndex < 0)
throw new ArgumentOutOfRangeException();
if (arrayIndex >= array.Length)
throw new ArgumentException("arrayIndex is greater than the length of the destination array.");
if (Count >= array.Length)
throw new ArgumentException("the Count property is larger than the size of the destination array.");
this.dict.Keys.CopyTo(array, arrayIndex);
}
///
/// Copies the specified number of elements of a System.Collections.Generic.HashSet object to an array,
/// starting at the specified array index.
///
/// The one-dimensional array that is the destination of the elements copied from the System.Collections.Generic.HashSet object. The array must have zero-based indexing.
/// The zero-based index in array at which copying begins.
/// The number of elements to copy to array.
/// array is null.
/// arrayIndex is less than 0. -or- count is less than 0.
/// arrayIndex is greater than the length of the destination array. -or- count is greater than the available space from the index to the end of the destination array.
public void CopyTo(T[] array, int arrayIndex, int count)
{
if (array == null)
throw new ArgumentNullException("array");
if (arrayIndex < 0 || count < 0)
throw new ArgumentOutOfRangeException();
if (arrayIndex >= array.Length)
throw new ArgumentException("arrayIndex is greater than the length of the destination array.");
if (count > array.Length - arrayIndex)
throw new ArgumentException("count is greater than the available space from the index to the end of the destination array.");
int copiedCount = 0;
int currentIndex = arrayIndex;
foreach (T item in this)
{
array[currentIndex] = item;
currentIndex++;
copiedCount++;
if (copiedCount >= count)
break;
}
}
///
/// Removes all elements in the specified collection from the current System.Collections.Generic.HashSet object.
///
/// The collection of items to remove from the System.Collections.Generic.HashSet object.
/// other is null.
public void ExceptWith(IEnumerable other)
{
if (other == null)
throw new ArgumentNullException("other");
foreach (T item in other)
this.dict.Remove(item);
}
///
/// Modifies the current System.Collections.Generic.HashSet object to contain
/// only elements that are present in that object and in the specified collection.
///
/// The collection to compare to the current System.Collections.Generic.HashSet object.
public void IntersectWith(IEnumerable other)
{
this.dict.Clear();
foreach (T item in other)
this.dict[item] = null;
}
///
/// Determines whether a System.Collections.Generic.HashSet object is a proper subset of the specified collection.
///
/// The collection to compare to the current System.Collections.Generic.HashSet object.
/// true if the System.Collections.Generic.HashSet object is a proper subset of other; otherwise, false.
/// other is null.
public bool IsProperSubsetOf(IEnumerable other)
{
return IsSubsetOf(other, true);
}
///
/// Determines whether a System.Collections.Generic.HashSet object is a subset of the specified collection.
///
/// The collection to compare to the current System.Collections.Generic.HashSet object.
/// true if the System.Collections.Generic.HashSet object is a subset of other; otherwise, false.
/// other is null.
public bool IsSubsetOf(IEnumerable other)
{
return IsSubsetOf(other, false);
}
private bool IsSubsetOf(IEnumerable other, bool proper)
{
if (other == null)
throw new ArgumentNullException("other");
int elementCount = 0;
int mathingCount = 0;
foreach (T item in other)
{
elementCount++;
if (this.dict.ContainsKey(item))
mathingCount++;
}
if (proper)
return mathingCount == this.dict.Count && elementCount > this.dict.Count;
else
return mathingCount == this.dict.Count;
}
///
/// Determines whether a System.Collections.Generic.HashSet object is a proper superset of the specified collection.
///
/// The collection to compare to the current System.Collections.Generic.HashSet object.
/// true if the System.Collections.Generic.HashSet object is a proper superset of other; otherwise, false.
/// other is null.
public bool IsProperSupersetOf(IEnumerable other)
{
return IsSupersetOf(other, true);
}
///
/// Determines whether a System.Collections.Generic.HashSet object is a superset of the specified collection.
///
/// The collection to compare to the current System.Collections.Generic.HashSet object.
/// true if the System.Collections.Generic.HashSet object is a superset of other; otherwise, false.
/// other is null.
public bool IsSupersetOf(IEnumerable other)
{
return IsSupersetOf(other, false);
}
private bool IsSupersetOf(IEnumerable other, bool proper)
{
if (other == null)
throw new ArgumentNullException("other");
int elementCount = 0;
foreach (T item in other)
{
elementCount++;
if (!this.dict.ContainsKey(item))
return false;
}
if (proper)
return elementCount < this.dict.Count;
else
return true;
}
///
/// Determines whether the current System.Collections.Generic.HashSet object overlaps the specified collection.
///
/// The collection to compare to the current System.Collections.Generic.HashSet object.
/// true if the System.Collections.Generic.HashSet object and other share at least one common element; otherwise, false.
/// other is null.
public bool Overlaps(IEnumerable other)
{
if (other == null)
throw new ArgumentNullException("other");
foreach (T item in other)
{
if (this.dict.ContainsKey(item))
return true;
}
return false;
}
///
/// Removes the specified element from a System.Collections.Generic.HashSet object.
///
/// The element to remove.
///
/// true if the element is successfully found and removed; otherwise, false.
/// This method returns false if item is not found in the System.Collections.Generic.HashSet object.
///
public bool Remove(T item)
{
if (this.dict.ContainsKey(item))
{
this.dict.Remove(item);
return true;
}
else
{
return false;
}
}
///
/// Removes all elements that match the conditions defined by the specified predicate from a System.Collections.Generic.HashSet collection.
///
/// The System.Predicate delegate that defines the conditions of the elements to remove.
/// The number of elements that were removed from the System.Collections.Generic.HashSet collection.
public int RemoveWhere(Predicate match)
{
int removeCount = 0;
foreach (KeyValuePair item in this.dict)
{
if (match(item.Key))
{
this.dict.Remove(item.Key);
removeCount++;
}
}
return removeCount;
}
///
/// Determines whether a System.Collections.Generic.HashSet object and the specified collection contain the same elements.
///
/// The collection to compare to the current System.Collections.Generic.HashSet object.
/// true if the System.Collections.Generic.HashSet object is equal to other; otherwise, false.
/// other is null.
public bool SetEquals(IEnumerable other)
{
if (other == null)
throw new ArgumentNullException("other");
int containsCount = 0;
foreach (T item in other)
{
if (!this.dict.ContainsKey(item))
return false;
else
containsCount++;
}
return containsCount == this.dict.Count;
}
///
/// Modifies the current System.Collections.Generic.HashSet object to contain only elements that are present either in that object or in the specified collection, but not both.
///
/// The collection to compare to the current System.Collections.Generic.HashSet object.
/// other is null.
public void SymmetricExceptWith(IEnumerable other)
{
if (other == null)
throw new ArgumentNullException("other");
HashSet tmpSet = new HashSet(other);
foreach (T item in tmpSet)
{
if (this.dict.ContainsKey(item))
this.dict.Remove(item);
else
this.dict[item] = null;
}
}
///
/// Sets the capacity of a System.Collections.Generic.HashSet object to the
/// actual number of elements it contains, rounded up to a nearby, implementation-specific
/// value.
///
public void TrimExcess()
{
//do nothing
}
///
/// Modifies the current System.Collections.Generic.HashSet object to contain
/// all elements that are present in both itself and in the specified collection.
///
/// The collection to compare to the current System.Collections.Generic.HashSet object.
/// other is null.
public void UnionWith(IEnumerable other)
{
if (other == null)
throw new ArgumentNullException("other");
foreach (T item in other)
if (!this.dict.ContainsKey(item))
this.dict[item] = null;
}
#endregion
#region ICollection, IEnumerable, IEnumerable成员
///
/// Returns an enumerator that iterates through a System.Collections.Generic.HashSet object.
///
/// A System.Collections.Generic.HashSet.Enumerator object for the System.Collections.Generic.HashSet object.
IEnumerator IEnumerable.GetEnumerator()
{
return this.dict.Keys.GetEnumerator();
}
void ICollection.Add(T item)
{
throw new NotImplementedException();
}
///
/// Gets a value indicating whether the is read-only.
///
///
/// true if the is read-only; otherwise, false.
///
public bool IsReadOnly
{
get { return false; }
}
///
/// Returns an enumerator that iterates through the collection.
///
///
/// A that can be used to iterate through the collection.
///
public IEnumerator GetEnumerator()
{
return this.dict.Keys.GetEnumerator();
}
#endregion
#region ISerializable 成员
///
/// Populates a with the data needed to serialize the target object.
///
/// The to populate with data. The destination (see ) for this serialization. The caller does not have the required permission.
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null) throw new ArgumentNullException("info");
dict.GetObjectData(info, context);
}
#endregion
#region IDeserializationCallback 成员
///
/// Runs when the entire object graph has been deserialized.
///
/// The object that initiated the callback. The functionality for this parameter is not currently implemented.
public void OnDeserialization(object sender)
{
this.dict.OnDeserialization(sender);
}
#endregion
#region Enumerator
///
/// Enumerates the elements of a System.Collections.Generic.HashSet object.
///
private struct Enumerator : IEnumerator, IDisposable, IEnumerator
{
///
/// Gets the element at the current position of the enumerator.
///
/// The element in the System.Collections.Generic.HashSet collection at the current position of the enumerator.
public T Current
{
get { throw new NotImplementedException(); }
}
///
/// Releases all resources used by a System.Collections.Generic.HashSet.Enumerator object.
///
public void Dispose()
{
throw new NotImplementedException();
}
///
/// Advances the enumerator to the next element of the System.Collections.Generic.HashSet collection.
///
/// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.
/// The collection was modified after the enumerator was created.
public bool MoveNext()
{
throw new NotImplementedException();
}
public void Reset()
{
throw new NotImplementedException();
}
object IEnumerator.Current
{
get { throw new NotImplementedException(); }
}
}
#endregion
}
}