剖析.NET Framework源码—数据结构List<T> (四)
(17)Reverse:2个重载。将整个List或其一部分反转
public void Reverse(int index, int count)
{
if (index < 0 || count < 0)
throw new ArgumentOutOfRangeException();
if (_size - index < count)
throw new ArgumentOutOfRangeException();
Array.Reverse(_items, index, count);
_version++;
}
值得注意的是,原来索引为index的元素反转之后索引变为index+(index+count-i-1)!
(18)Sort:将List或其一部分进行排序
//comparer为比较器,在元素相互比较过程中会用到
//如果比较器comparer为null,则排序过程中则使用元素的IComparable接 口进行比较,因此,必须保证数组中的所有元素都实现了IComparable接口
public void Sort(int index, int count, IComparer<T> comparer)
{
if (index < 0 || count < 0)
{
throw new ArgumentOutOfRangeException();
}
if (_size - index < count)
throw new ArgumentOutOfRangeException();
//使用Array.Sort方法对元素进行排序
Array.Sort<T>(_items, index, count, comparer);
_version++;
}
//使用默认的比较器(元素的IComparable接口实现)
public void Sort()
{
Sort(0, Count, null);
}
// 使用提供的比较器comparer
public void Sort(IComparer<T> comparer)
{
Sort(0, Count, comparer);
}
(20)TrimExcess:将容量设置为List中实际元素的个数
//为了完全清除List中的元素并且释放list引用的全部内存,执行以下语句:
// list.Clear();
// list.TrimExcess();
public void TrimExcess()
{
int threshold = (int)(((double)_items.Length) * 0.9);
if (_size < threshold)
{
Capacity = _size;
}
}
这个方法中有一个局部变量threshold,表示一个阈值,它是List容量的0.9倍!只有当List中实际存储的元素个数小于这个阈值时,List才会被紧缩!即是把List的容量设置为其实际存储元素的个数,以便节约内存空间。
(20)GetEnumerator:返回一个循环访问集合的枚举数
public Enumerator GetEnumerator()
{
//利用当前List构造枚举数
return new Enumerator(this);
}
(21)Enumerator :用于循环访问集合的枚举数
[Serializable()]
public struct Enumerator : IEnumerator<T>, System.Collections.IEnumerator
{
private List<T> list;
private int index; //当前的索引位置
private int version; //list的版本号
private T current; //当前元素
//构造出指定List的枚举数
internal Enumerator(List<T> list)
{
this.list = list;
index = 0;
version = list._version;
current = default(T);
}
public bool MoveNext()
{
List<T> localList = list;
//检查version值是否同步,如果不同步说明在枚举过程中对元素进 行了修改,则返回MoveNextRare方法,后者直接抛出异常
if (version == localList._version && ((uint)index < (uint)localList._size))
{
current = localList._items[index];
index++;
return true;
}
return MoveNextRare();
}
private bool MoveNextRare()
{
if (version != list._version)
{
throw new InvalidOperationException();
}
index = list._size + 1;
current = default(T);
return false;
}
public T Current
{
get
{
return current;
}
}
Object System.Collections.IEnumerator.Current
{
get
{
if (index == 0 || index == list._size + 1)
{
throw new InvalidOperationException();
}
return Current;
}
}
void System.Collections.IEnumerator.Reset()
{
if (version != list._version)
{
throw new InvalidOperationException();
}
index = 0;
current = default(T);
}
}
(22)BinarySearch:对分检索算法在已排序的List或其一部分中查找特定元素!
//利用二分查找算法搜索整个List或其一部分是否包含指定元素item!元素之间的相互比较时使用给定的comparer比较器,如果比较器为空,则使用元素的IComparable接口,因此数组元素和需要被查找的元素都要求实现IComparable接口,这个算法假设给定的List是有序的,否则结果会不正确!
//这个方法返回所要查找元素从0开始的索引,如果List中不包含此元素item,则返回一个负数!这个负数是List中大于item的第一个元素的索引的按位求补,如果没有更大的元素,则为count的按位求补。
public int BinarySearch(int index, int count, T item, IComparer<T> comparer)
{
if (index < 0 || count < 0)
throw new ArgumentOutOfRangeException();
if (_size - index < count)
throw new ArgumentException();
return Array.BinarySearch<T>(_items, index, count, item, comparer);
}