zoukankan      html  css  js  c++  java
  • C# Dictionary字典源码分析与自定义Dictionary字典

    C# Dictionary字典源码分析与自定义Dictionary字典

    官网源码地址:

    https://referencesource.microsoft.com/#mscorlib/system/collections/generic/dictionary.cs

    关键点

    • Dictionary实际容器为Entry[] entries 结构体数组
    private struct Entry
    {
       public int hashCode;
       public int next;
       public TKey key;
       public TValue value;
    }
    
    • entries数组默认长度为3
    • 如果初始化指定长度 entries数组长度为大于指定长度最接近的质数
    • Dictionary查找元素的时间复杂度接近O(1)是因为
      • 定义了一个int[] buckets Hash桶数组
      • 获取key了hashCode
      • 用hashCode除buckets长度取余做为索引(这也是为什么长度为质数的原因)
    • 防止hashCode冲突Dictionary使用了拉链法
      • 使用Entry.next保存冲突项索
    • 当添加值时冲突达到100次会使用新的hashCode方法解决
    • 当Entry[] entries或int[] buckets满了的时候会自动扩了当前容量的2倍
    • 扩容后会重现计算hashcode赋值索引
    • 查找元素是会判断hashcode和key.Equals

    优化点

    • 已知容器大小的情况 直接初始化对应大小
    • key最好用简单类型
      • 如果一定要用枚举或引用类型
      • 初始化字典的时候赋值对比函数
      • 或者实现IEquatable
    • 获取值得时候使用TryGetValue不需要先判断ContainsKey

    自定义Dictionary字典

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Runtime.Serialization;
    
    public interface IMyDictionary<TKey, TValue> : IEnumerable, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>
    {
        TValue this[TKey key] { get; set; }
    
        ICollection<TKey> Keys { get; }
        ICollection<TValue> Values { get; }
    
        void Add(TKey key, TValue value);
        bool ContainsKey(TKey key);
        bool Remove(TKey key);
        bool TryGetValue(TKey key, out TValue value);
    }
    
    
    public class MyDictionary<TKey, TValue>
    {
        private struct Entry
        {
            public int hashCode;
            public int next;
            public TKey key;
            public TValue value;
        }
        /// <summary>
        /// Hash桶
        /// </summary>
        private int[] buckets;
        /// <summary>
        /// 所有键值对条目数组
        /// </summary>
        private Entry[] entries;
        /// <summary>
        /// 当前entries的index位置
        /// </summary>
        private int count;
        /// <summary>
        /// 当前版本,防止迭代过程中集合被更改
        /// </summary>
        private int version;
        /// <summary>
        /// entries空闲索引
        /// </summary>
        private int freeList;
        /// <summary>
        /// entries空闲数量
        /// </summary>
        private int freeCount;
        /// <summary>
        /// 对比函数
        /// </summary>
        private IEqualityComparer<TKey> comparer;
        /// <summary>
        /// key集合
        /// </summary>
        private KeyCollection keys;
        /// <summary>
        /// value集合
        /// </summary>
        private ValueCollection values;
    
        public MyDictionary() : this(0, null) { }
    
        public MyDictionary(IEqualityComparer<TKey> comparer) : this(0, comparer) { }
    
        public MyDictionary(IDictionary<TKey, TValue> dictionary) : this(dictionary, null) { }
    
        public MyDictionary(int capacity) : this(capacity, null) { }
    
        public MyDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) : this(dictionary != null ? dictionary.Count : 0, comparer)
        {
            if (dictionary == null) { return; }//异常
    
            foreach (KeyValuePair<TKey, TValue> pair in dictionary)
            {
                Add(pair.Key, pair.Value);
            }
        }
    
        public MyDictionary(int capacity, IEqualityComparer<TKey> comparer)
        {
            if (capacity < 0) { throw new Exception("capacity 异常"); }
            if (capacity > 0) Initialize(capacity);
            this.comparer = comparer ?? EqualityComparer<TKey>.Default;
        }
    
        public TValue this[TKey key]
        {
            get
            {
                int i = FindEntry(key);
                if (i >= 0) return entries[i].value;
    
                throw new Exception("TKey 异常");
            }
            set
            {
                Insert(key, value, false);
            }
        }
    
        public IEqualityComparer<TKey> Comparer
        {
            get { return comparer; }
        }
    
        public KeyCollection Keys
        {
            get
            {
                if (keys == null) keys = new KeyCollection(this);
                return keys;
            }
        }
        public ValueCollection Values
        {
            get
            {
                if (values == null) values = new ValueCollection(this);
                return values;
            }
        }
        public int Count
        {
            get { return count - freeCount; }
        }
    
        public void Add(TKey key, TValue value)
        {
            Insert(key, value, true);
        }
        public void Clear()
        {
            if (count > 0)
            {
                for (int i = 0; i < buckets.Length; i++) buckets[i] = -1;
                Array.Clear(entries, 0, count);
                freeList = -1;
                count = 0;
                freeCount = 0;
                version++;
            }
        }
        public bool ContainsKey(TKey key)
        {
            return FindEntry(key) >= 0;
        }
        public bool ContainsValue(TValue value)
        {
            if (value == null)
            {
                for (int i = 0; i < count; i++)
                {
                    if (entries[i].hashCode >= 0 && entries[i].value == null) return true;
                }
            }
            else
            {
                EqualityComparer<TValue> c = EqualityComparer<TValue>.Default;
                for (int i = 0; i < count; i++)
                {
                    if (entries[i].hashCode >= 0 && c.Equals(entries[i].value, value)) return true;
                }
            }
            return false;
        }
        public Enumerator GetEnumerator()
        {
            return new Enumerator(this, Enumerator.KeyValuePair);
        }
        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
        {
        }
        public virtual void OnDeserialization(object sender)
        {
    
        }
        public bool Remove(TKey key)
        {
            if (key == null)
            {
                throw new Exception("异常");
            }
    
            if (buckets != null)
            {
                int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
                int bucket = hashCode % buckets.Length;
                int last = -1;
                for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next)
                {
                    if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
                    {
                        if (last < 0)
                        {
                            buckets[bucket] = entries[i].next;//找到元素后,如果last< 0,代表当前是bucket中最后一个元素,那么直接让bucket内下标赋值为 entries[i].next即可
                        }
                        else
                        {
                            entries[last].next = entries[i].next;//last不小于0,代表当前元素处于bucket单链表中间位置,需要将该元素的头结点和尾节点相连起来,防止链表中断
                        }
                        entries[i].hashCode = -1;
                        entries[i].next = freeList;
                        entries[i].key = default(TKey);
                        entries[i].value = default(TValue);
                        freeList = i;//freeList等于当前的entry位置,下一次Add元素会优先Add到该位置
                        freeCount++;
                        version++;
                        return true;
                    }
                }
            }
            return false;
        }
        public bool TryGetValue(TKey key, out TValue value)
        {
            int i = FindEntry(key);
            if (i >= 0)
            {
                value = entries[i].value;
                return true;
            }
            value = default(TValue);
            return false;
        }
    
    
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="capacity">容量</param>
        private void Initialize(int capacity)
        {
            int size = HashHelpers.GetPrime(capacity);//获取该容量匹配的质数
            buckets = new int[size];//初始化桶数组
            for (int i = 0; i < buckets.Length; i++) buckets[i] = -1;//桶数组全部赋值为-1
            entries = new Entry[size];//初始化容量
            freeList = -1;
        }
    
        /// <summary>
        /// 插入
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="add"></param>
        private void Insert(TKey key, TValue value, bool add)
        {
    
            if (key == null)
            {
                throw new Exception("key == null 异常");
            }
    
            if (buckets == null) Initialize(0);
            int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;//01111111 11111111 11111111 11111111 忽略符号位
            int targetBucket = hashCode % buckets.Length;//获得hashCode在buckets中存放在位置
    
    
            int collisionCount = 0;//冲突数量
    
            //从hash桶中获取索引     i = entries[i].next 继续获取拉链下一个数据
            for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next)
            {
                if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))//如果键值对条目数组索引位置hashCode等于key的hashCode 且key相等 赋值
                {
                    if (add)
                    {
                        throw new Exception("key已存在 异常");
                    }
                    entries[i].value = value;
                    version++;
                    return;
                }
                //如果不相等 冲突+1
                collisionCount++;
            }
    
            //如果entries[i].next=-1 下一个拉链数据为空则执行下面的操作
            //创建一个拉链数据
    
            int index;
            if (freeCount > 0)//有空闲位置
            {
                index = freeList;
                freeList = entries[index].next;
                freeCount--;
            }
            else
            {
                if (count == entries.Length)//如果键值对条目数组已满
                {
                    Resize();//调整大小
                    targetBucket = hashCode % buckets.Length;//重现获取hashCode在buckets中存放在位置
                }
                index = count;//取键值对条目数组空闲的位置
                count++;
            }
    
            entries[index].hashCode = hashCode;
            entries[index].next = buckets[targetBucket];//把原hash桶中索引的键值对条目索引赋值到当前键值对条目的下一个位
            entries[index].key = key;
            entries[index].value = value;
            buckets[targetBucket] = index;//替换hash桶位的指向
            version++;
    
            // 如果碰撞次数大于设置的最大碰撞次数,那么触发Hash碰撞扩容
            if (collisionCount > 100 && (comparer == null || comparer == EqualityComparer<TKey>.Default))
            {
                comparer = EqualityComparer<TKey>.Default;//使用新的对比hash函数
                Resize(entries.Length, true);
            }
    
    
        }
    
        /// <summary>
        /// 查找键值对条目
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        private int FindEntry(TKey key)
        {
            if (key == null)
            {
                throw new Exception("key 异常");
            }
    
            if (buckets != null)
            {
                int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
                for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entries[i].next)
                {
                    //判断hashCode相等且key相等 则返回索引   如果不想等 获取next
                    if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) return i;
                }
            }
            return -1;
        }
    
        /// <summary>
        /// 调整大小
        /// </summary>
        private void Resize()
        {
            Resize(HashHelpers.ExpandPrime(count), false);
        }
    
        /// <summary>
        /// 调整大小
        /// </summary>
        /// <param name="newSize">新da'xia</param>
        /// <param name="forceNewHashCodes">强制使用新的hashcode方法</param>
        private void Resize(int newSize, bool forceNewHashCodes)
        {
            if (newSize >= entries.Length == false) throw new Exception("newSize 异常");
    
            int[] newBuckets = new int[newSize];//新的hash桶
            for (int i = 0; i < newBuckets.Length; i++) newBuckets[i] = -1;
    
            Entry[] newEntries = new Entry[newSize];//新的键值对条目数组
    
            Array.Copy(entries, 0, newEntries, 0, count);//拷贝老的键值对条目数组到新的键值对条目数组
    
            if (forceNewHashCodes)//强制使用新的hashcode
            {
                for (int i = 0; i < count; i++)
                {
                    if (newEntries[i].hashCode != -1)//过滤未使用的
                    {
                        newEntries[i].hashCode = (comparer.GetHashCode(newEntries[i].key) & 0x7FFFFFFF);//使用新HashCode函数重新计算Hash值
                    }
                }
            }
            for (int i = 0; i < count; i++)
            {
                int bucket = newEntries[i].hashCode % newSize;//获取hash桶索引
                newEntries[i].next = newBuckets[bucket];//第一次 newBuckets[bucket]==-1 第n次 newBuckets[bucket]==上次赋值索引
                newBuckets[bucket] = i;//赋值到hash桶
            }
            buckets = newBuckets;
            entries = newEntries;
        }
    
        private void CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
        {
            if (array == null)
            {
                throw new Exception("异常");
            }
    
            if (index < 0 || index > array.Length)
            {
                throw new Exception("异常");
            }
    
            if (array.Length - index < Count)
            {
                throw new Exception("异常");
            }
    
            int count = this.count;
            Entry[] entries = this.entries;
            for (int i = 0; i < count; i++)
            {
                if (entries[i].hashCode >= 0)
                {
                    array[index++] = new KeyValuePair<TKey, TValue>(entries[i].key, entries[i].value);
                }
            }
        }
    
        public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>,
                IDictionaryEnumerator
        {
            private MyDictionary<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 = 1;
            internal const int KeyValuePair = 2;
    
            internal Enumerator(MyDictionary<TKey, TValue> dictionary, int getEnumeratorRetType)
            {
                this.dictionary = dictionary;
                version = dictionary.version;
                index = 0;
                this.getEnumeratorRetType = getEnumeratorRetType;
                current = new KeyValuePair<TKey, TValue>();
            }
    
            public bool MoveNext()
            {
                if (version != dictionary.version)
                {
                    throw new Exception("异常");
                }
    
                // 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 >= 0)
                    {
                        current = new KeyValuePair<TKey, TValue>(dictionary.entries[index].key, dictionary.entries[index].value);
                        index++;
                        return true;
                    }
                    index++;
                }
    
                index = dictionary.count + 1;
                current = new KeyValuePair<TKey, TValue>();
                return false;
            }
    
            public KeyValuePair<TKey, TValue> Current
            {
                get { return current; }
            }
    
            public void Dispose()
            {
            }
    
            object IEnumerator.Current
            {
                get
                {
                    if (index == 0 || (index == dictionary.count + 1))
                    {
                        throw new Exception("异常");
                    }
    
                    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)
                {
                    throw new Exception("异常");
                }
    
                index = 0;
                current = new KeyValuePair<TKey, TValue>();
            }
    
            DictionaryEntry IDictionaryEnumerator.Entry
            {
                get
                {
                    if (index == 0 || (index == dictionary.count + 1))
                    {
                        throw new Exception("异常");
                    }
    
                    return new DictionaryEntry(current.Key, current.Value);
                }
            }
    
            object IDictionaryEnumerator.Key
            {
                get
                {
                    if (index == 0 || (index == dictionary.count + 1))
                    {
                        throw new Exception("异常");
                    }
    
                    return current.Key;
                }
            }
    
            object IDictionaryEnumerator.Value
            {
                get
                {
                    if (index == 0 || (index == dictionary.count + 1))
                    {
                        throw new Exception("异常");
                    }
    
                    return current.Value;
                }
            }
        }
    
        public sealed class KeyCollection : ICollection<TKey>, ICollection
        {
            private MyDictionary<TKey, TValue> dictionary;
    
            public KeyCollection(MyDictionary<TKey, TValue> dictionary)
            {
                if (dictionary == null)
                {
                    throw new Exception("dictionary == null 异常");
                }
                this.dictionary = dictionary;
            }
    
            public Enumerator GetEnumerator()
            {
                return new Enumerator(dictionary);
            }
    
            public void CopyTo(TKey[] array, int index)
            {
                if (array == null)
                {
                    throw new Exception("array == null 异常");
                }
    
                if (index < 0 || index > array.Length)
                {
                    throw new Exception("index < 0 || index > array.Length 异常");
                }
    
                if (array.Length - index < dictionary.Count)
                {
                    throw new Exception("异常");
                }
    
                int count = dictionary.count;
                Entry[] entries = dictionary.entries;
                for (int i = 0; i < count; i++)
                {
                    if (entries[i].hashCode >= 0) array[index++] = entries[i].key;
                }
            }
    
            public int Count
            {
                get { return dictionary.Count; }
            }
    
            bool ICollection<TKey>.IsReadOnly
            {
                get { return true; }
            }
    
            void ICollection<TKey>.Add(TKey item)
            {
                throw new Exception("异常");
            }
    
            void ICollection<TKey>.Clear()
            {
                throw new Exception("异常");
            }
    
            bool ICollection<TKey>.Contains(TKey item)
            {
                return dictionary.ContainsKey(item);
            }
    
            bool ICollection<TKey>.Remove(TKey item)
            {
                throw new Exception("异常");
            }
    
            IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator()
            {
                return new Enumerator(dictionary);
            }
    
            IEnumerator IEnumerable.GetEnumerator()
            {
                return new Enumerator(dictionary);
            }
    
            void ICollection.CopyTo(Array array, int index)
            {
                if (array == null)
                {
                    throw new Exception("异常");
                }
    
                if (array.Rank != 1)
                {
                    throw new Exception("异常");
                }
    
                if (array.GetLowerBound(0) != 0)
                {
                    throw new Exception("异常");
                }
    
                if (index < 0 || index > array.Length)
                {
                    throw new Exception("异常");
                }
    
                if (array.Length - index < dictionary.Count)
                {
                    throw new Exception("异常");
                }
    
                TKey[] keys = array as TKey[];
                if (keys != null)
                {
                    CopyTo(keys, index);
                }
                else
                {
                    object[] objects = array as object[];
                    if (objects == null)
                    {
                        throw new Exception("异常");
                    }
    
                    int count = dictionary.count;
                    Entry[] entries = dictionary.entries;
                    try
                    {
                        for (int i = 0; i < count; i++)
                        {
                            if (entries[i].hashCode >= 0) objects[index++] = entries[i].key;
                        }
                    }
                    catch (ArrayTypeMismatchException)
                    {
                        throw new Exception("异常");
                    }
                }
            }
    
            bool ICollection.IsSynchronized
            {
                get { return false; }
            }
    
            Object ICollection.SyncRoot
            {
                get { return ((ICollection)dictionary).SyncRoot; }
            }
    
            [Serializable]
            public struct Enumerator : IEnumerator<TKey>, System.Collections.IEnumerator
            {
                private MyDictionary<TKey, TValue> dictionary;
                private int index;
                private int version;
                private TKey currentKey;
    
                internal Enumerator(MyDictionary<TKey, TValue> dictionary)
                {
                    this.dictionary = dictionary;
                    version = dictionary.version;
                    index = 0;
                    currentKey = default(TKey);
                }
    
                public void Dispose()
                {
                }
    
                public bool MoveNext()
                {
                    if (version != dictionary.version)
                    {
                        throw new Exception("异常");
                    }
    
                    while ((uint)index < (uint)dictionary.count)
                    {
                        if (dictionary.entries[index].hashCode >= 0)
                        {
                            currentKey = dictionary.entries[index].key;
                            index++;
                            return true;
                        }
                        index++;
                    }
    
                    index = dictionary.count + 1;
                    currentKey = default(TKey);
                    return false;
                }
    
                public TKey Current
                {
                    get
                    {
                        return currentKey;
                    }
                }
    
                Object System.Collections.IEnumerator.Current
                {
                    get
                    {
                        if (index == 0 || (index == dictionary.count + 1))
                        {
                            throw new Exception("异常");
                        }
    
                        return currentKey;
                    }
                }
    
                void System.Collections.IEnumerator.Reset()
                {
                    if (version != dictionary.version)
                    {
                        throw new Exception("异常");
                    }
    
                    index = 0;
                    currentKey = default(TKey);
                }
            }
        }
    
        public sealed class ValueCollection : ICollection<TValue>, ICollection
        {
            private MyDictionary<TKey, TValue> dictionary;
    
            public ValueCollection(MyDictionary<TKey, TValue> dictionary)
            {
                if (dictionary == null)
                {
                    throw new Exception("异常");
                }
                this.dictionary = dictionary;
            }
    
            public Enumerator GetEnumerator()
            {
                return new Enumerator(dictionary);
            }
    
            public void CopyTo(TValue[] array, int index)
            {
                if (array == null)
                {
                    throw new Exception("异常");
                }
    
                if (index < 0 || index > array.Length)
                {
                    throw new Exception("异常");
                }
    
                if (array.Length - index < dictionary.Count)
                {
                    throw new Exception("异常");
                }
    
                int count = dictionary.count;
                Entry[] entries = dictionary.entries;
                for (int i = 0; i < count; i++)
                {
                    if (entries[i].hashCode >= 0) array[index++] = entries[i].value;
                }
            }
    
            public int Count
            {
                get { return dictionary.Count; }
            }
    
            bool ICollection<TValue>.IsReadOnly
            {
                get { return true; }
            }
    
            void ICollection<TValue>.Add(TValue item)
            {
                throw new Exception("异常");
            }
    
            bool ICollection<TValue>.Remove(TValue item)
            {
                throw new Exception("异常");
            }
    
            void ICollection<TValue>.Clear()
            {
                throw new Exception("异常");
            }
    
            bool ICollection<TValue>.Contains(TValue item)
            {
                return dictionary.ContainsValue(item);
            }
    
            IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator()
            {
                return new Enumerator(dictionary);
            }
    
            IEnumerator IEnumerable.GetEnumerator()
            {
                return new Enumerator(dictionary);
            }
    
            void ICollection.CopyTo(Array array, int index)
            {
                if (array == null)
                {
                    throw new Exception("异常");
                }
    
                if (array.Rank != 1)
                {
                    throw new Exception("异常");
                }
    
                if (array.GetLowerBound(0) != 0)
                {
                    throw new Exception("异常");
                }
    
                if (index < 0 || index > array.Length)
                {
                    throw new Exception("异常");
                }
    
                if (array.Length - index < dictionary.Count)
                    throw new Exception("异常");
    
                TValue[] values = array as TValue[];
                if (values != null)
                {
                    CopyTo(values, index);
                }
                else
                {
                    object[] objects = array as object[];
                    if (objects == null)
                    {
                        throw new Exception("异常");
                    }
    
                    int count = dictionary.count;
                    Entry[] entries = dictionary.entries;
                    try
                    {
                        for (int i = 0; i < count; i++)
                        {
                            if (entries[i].hashCode >= 0) objects[index++] = entries[i].value;
                        }
                    }
                    catch (ArrayTypeMismatchException)
                    {
                        throw new Exception("异常");
                        throw new Exception("异常");
                    }
                }
            }
    
            bool ICollection.IsSynchronized
            {
                get { return false; }
            }
    
            Object ICollection.SyncRoot
            {
                get { return ((ICollection)dictionary).SyncRoot; }
            }
    
            [Serializable]
            public struct Enumerator : IEnumerator<TValue>, System.Collections.IEnumerator
            {
                private MyDictionary<TKey, TValue> dictionary;
                private int index;
                private int version;
                private TValue currentValue;
    
                internal Enumerator(MyDictionary<TKey, TValue> dictionary)
                {
                    this.dictionary = dictionary;
                    version = dictionary.version;
                    index = 0;
                    currentValue = default(TValue);
                }
    
                public void Dispose()
                {
                }
    
                public bool MoveNext()
                {
                    if (version != dictionary.version)
                    {
                        throw new Exception("异常");
                    }
    
                    while ((uint)index < (uint)dictionary.count)
                    {
                        if (dictionary.entries[index].hashCode >= 0)
                        {
                            currentValue = dictionary.entries[index].value;
                            index++;
                            return true;
                        }
                        index++;
                    }
                    index = dictionary.count + 1;
                    currentValue = default(TValue);
                    return false;
                }
    
                public TValue Current
                {
                    get
                    {
                        return currentValue;
                    }
                }
    
                Object System.Collections.IEnumerator.Current
                {
                    get
                    {
                        if (index == 0 || (index == dictionary.count + 1))
                        {
                            throw new Exception("异常");
                        }
    
                        return currentValue;
                    }
                }
    
                void System.Collections.IEnumerator.Reset()
                {
                    if (version != dictionary.version)
                    {
                        throw new Exception("异常");
                    }
                    index = 0;
                    currentValue = default(TValue);
                }
            }
        }
    }
    
    using System;
    
    public class HashHelpers
    {
        public static readonly int[] primes = {
                3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919,
                1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591,
                17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437,
                187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263,
                1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369};
    
        /// <summary>
        /// 获取质数
        /// </summary>
        /// <param name="min">最小值</param>
        /// <returns></returns>
        public static int GetPrime(int min)
        {
            if (min < 0) { return -1; }//异常
    
    
            for (int i = 0; i < primes.Length; i++)
            {
                int prime = primes[i];
                if (prime >= min) return prime;
            }
    
            //outside of our predefined table. 
            //compute the hard way. 
            for (int i = (min | 1); i < Int32.MaxValue; i += 2)
            {
                if (IsPrime(i) && ((i - 1) % 101 != 0))
                    return i;
            }
            return min;
        }
    
        /// <summary>
        /// 判断是否为质数(素数)
        /// </summary>
        /// <param name="candidate"></param>
        /// <returns></returns>
        public static bool IsPrime(int candidate)
        {
            //与0000 0001位运算  可以把奇数偶数 刷选出来,因为偶数不是质数(2除外)
            if ((candidate & 1) != 0)
            {
                int limit = (int)Math.Sqrt(candidate);//求根号 相当于乘法中的中位数
                for (int divisor = 3; divisor <= limit; divisor += 2)//每次+2是跳过 偶数
                {
                    if ((candidate % divisor) == 0)
                        return false;
                }
                return true;
            }
            return (candidate == 2);//最后这个保证2也是质数
        }
    
        public static int ExpandPrime(int oldSize)
        {
            int newSize = 2 * oldSize;
    
            // Allow the hashtables to grow to maximum possible size (~2G elements) before encoutering capacity overflow.
            // Note that this check works even when _items.Length overflowed thanks to the (uint) cast
            if ((uint)newSize > 0x7FEFFFFD && 0x7FEFFFFD > oldSize)
            {
                throw new Exception("oldSize 异常");
            }
    
            return GetPrime(newSize);
        }
    }
    
  • 相关阅读:
    Java并发编程:线程池的使用
    AlarmManager与PendingIntent
    ConnectivityManager与检查网络连接的使用
    IntentService的使用
    Service(Local Service)简介
    Looper、Hander、HandlerThread
    XML_PULL解析
    android AsyncTask 的使用(转载)
    android 连接网络的简单实例
    xml drawable
  • 原文地址:https://www.cnblogs.com/zouqiang/p/13094018.html
Copyright © 2011-2022 走看看