5.1. ISet HashSet
ISet:ICollection
4个实现类
system.dll
1. SortedSet<T>
2. TreeSet<T>
3. TreeSubSet
system.core.dll
4. HashSet<T>
ISet method
new bool Add(T item);
//交差并补
void UnionWith(IEnumerable<T> other); //并集 A UNION B
void IntersectWith(IEnumerable<T> other); //交集 A AND B
void ExceptWith(IEnumerable<T> other);//差集 A NOT B
void SymmetricExceptWith(IEnumerable<T> other);//A NOR B A和B的联集
//包含关系判断
bool IsSubsetOf(IEnumerable<T> other); //set 是否是other的子集,other要大
bool IsProperSupersetOf(IEnumerable<T> other); //set 是否是other的子集,other要大,set!=other
bool IsSupersetOf(IEnumerable<T> other); //确定当前集是否为指定集合的超集。
bool IsProperSubsetOf(IEnumerable<T> other); //确定当前集是否为指定集合的真(严格)子集。
//包含任何相同元素
bool Overlaps(IEnumerable<T> other); //有交集吗
// 完全相等
bool SetEquals(IEnumerable<T> other); //集合元素完全相等
HashSet system.core.dll
内存存储实现几乎Dictionary<TKey,TValue>一样,都是双散列
其实重要的不是不重复,而是hash,而是获取,新增,修改是O(1)
1. int[] m_buckets;
2. Slot[] m_slots; //存value和hashcode
3. m_count
接口继承
ISet<T>,
ICollection<T>,
ISerializable...
保证不重复的秘密
这个其实简单,而且不重要,你用普通数组都可以做到数据不重复,只是每次添加都遍历判断下
而这里hashset只是在dictionary抛出异常的地方选择不抛出异常
method
AddIfNotPresent(T value); //类似Dictionary中的Insert(Tkey,TValue,bool) 只是新增重复的时候没有抛出异常
重点是怎么来实现ISet的呢
并集
public UnionWith(IEnumerable<T> other)
{
foreach(T item in other){AddIfNotPresent(item)};
}
交集
比较复杂,但是好在hashset获取数据是O(1),不需要循环对比,所以只要循环other一遍就可以了,并且为了记录下是否存在,所以需要使用bithelp来定义bit数组,
如果是0,1这种简单的操作是可以使用bit数组来解决内存的 (比如 System.Collections.BitArray mscorlib.dll)
SortedSet
继承
ISet<T>,
ICollection<T>,
ICollection,ISerializable,IDeserializationCallback,IReadOnlyCollection<T>
内部
Node root;
IComparer<T> comparer;
int count;
int version
Object _syncRoot;
ctor
1. SortedSet(){comparer=Comparer<T>.Default;}
2. SortedSet(IComparer<T>){}
3. SortedSet<IEnumerable<T> collection){}
4. SortedSet<IEnumerable<T> collection,IComparer<T> comparer){}
这就是