Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

.NET框架-HashSet源码分析

$
0
0

HashSet表示值的集合。

源码中,获取哈希吗的算法:

        private int InternalGetHashCode(T item)
        {
            if (item == null)
            {
                return 0;
            }
            return _comparer.GetHashCode(item) & Lower31BitMask;
        }
 // store lower 31 bits of hash code
private const int Lower31BitMask = 0x7FFFFFFF;

再看一个内部封装的,加入一个元素到集合中,

        //Returns true if added and false if already present
        private bool AddIfNotPresent(T value)
        {
            if (_buckets == null)
            {
                Initialize(0);
            }

            int hashCode = InternalGetHashCode(value);
            int bucket = hashCode % _buckets.Length;
            for (int i = _buckets[bucket] - 1; i >= 0; i = _slots[i].next)
            {
                if (_slots[i].hashCode == hashCode && _comparer.Equals(_slots[i].value, value))
                {
                    return false;
                }

            }

            int index;
            if (_freeList >= 0)
            {
                index = _freeList;
                _freeList = _slots[index].next;
            }
            else
            {
                if (_lastIndex == _slots.Length)
                {
                    IncreaseCapacity();
                    // this will change during resize
                    bucket = hashCode % _buckets.Length;
                }
                index = _lastIndex;
                _lastIndex++;
            }
            _slots[index].hashCode = hashCode;
            _slots[index].value = value;
            _slots[index].next = _buckets[bucket] - 1;
            _buckets[bucket] = index + 1;
            _count++;
            _version++;
            return true;
        }

看了以上封装的这个方法后,我们再看下一个公开的API,

        /// <summary>
        /// Add item to this hashset. This is the explicit implementation of the ICollection<T>
        /// interface. The other Add method returns bool indicating whether item was added.
        /// </summary>
        /// <param name="item">item to add</param>
        void ICollection<T>.Add(T item)
        {
            AddIfNotPresent(item);
        }

再看一个完成添加元素到集合的API,

        /// <summary>
        /// Add item to this HashSet. Returns bool indicating whether item was added (won't be 
        /// added if already present)
        /// </summary>
        /// <param name="item"></param>
        /// <returns>true if added, false if already present</returns>
        public bool Add(T item)
        {
            return AddIfNotPresent(item);
        }

继续分析一个合并两个集合的API,它用到了内部私有的添加元素到集合的方法,

       /// <summary>
        /// Take the union of this HashSet with other. Modifies this set.
        /// 
        /// Implementation note: GetSuggestedCapacity (to increase capacity in advance avoiding 
        /// multiple resizes ended up not being useful in practice; quickly gets to the 
        /// point where it's a wasteful check.
        /// </summary>
        /// <param name="other">enumerable with items to add</param>
        public void UnionWith(IEnumerable<T> other)
        {
            if (other == null)
            {
                throw new ArgumentNullException(nameof(other));
            }
            Contract.EndContractBlock();

            foreach (T item in other)
            {
                AddIfNotPresent(item);
            }
        }

总结,微软在实现HashSet,添加某个元素到集合时,内部私有实现了一个AddIfNotPresent方法,在它内部用到了InternalGetHashCode算法获取添加元素的哈希值。暴露的这些添加元素的API都是调用了AddIfNotPresent方法。这便是添加元素到哈希表的实现细节。

作者:daigualu 发表于2017/3/14 23:02:42 原文链接
阅读:72 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>