C \ # ArrayList 소스 분석

소스 코드 버 전 은. NET Framework 4.6.1 입 니 다.
투입 도 있 고 산출 도 있다.
배열 은 C \ # 에서 가장 기본 적 인 데이터 형식 으로 초기 화 되면 용량 이 확 정 됩 니 다.동적 으로 용량 을 늘 리 려 면 집합 은 이 수 요 를 만족 시 킬 수 있다.Array List 는 C \ # 에서 가장 많이 사용 되 고 가장 기본 적 인 동적 배열 입 니 다.
Array List 는 System. collections 에서 IList 인터페이스 (IList: 색인 에 따라 접근 할 수 있 는 비 일반적인 집합 대상 을 표시 합 니 다) 를 실현 합 니 다.
그렇다면 Array List 는 어떤 일 을 할 수 있 을 까?1. 동적 확장 가능;2. 삽입 / 삭제 가 비교적 편리 하 다.
쓸데없는 말 이 많아 서 배가 뒤 집 히 는 것 을 방지 하기 위해 코드 를 올 립 니 다.
  • Array List 의 데 이 터 는 내부 배열 로 유지 되 고 있 습 니 다. 개인 적 인 Object 데이터 (Object 당신 이 만능 조물주 군요 ~)
  • private Object[] _item[];
    private int _size;//ArrayList   
    private const int _defaultCapacity = 4;//     
    private static readonly Object[] emptyArray = EmptyArray<Object>.Value; //      

    - 요소 추가: Add (Object), AddRange (ICollection), Insert (Int 32, Object), InsertRange (Int 32, ICollection).
  • Add (Object): 대상 을 Array List 의 끝 에 추가 합 니 다.
  •      public virtual int Add(Object value) {
                Contract.Ensures(Contract.Result<int>() >= 0);//    ,         0
                //         , ArrayList                 ,    
                if (_size == _items.Length) EnsureCapacity(_size + 1);
                _items[_size] = value;// ArrayList        
                _version++;
                return _size++;//    ArrayList   
            }
         //         ,            2 ,      long     
         private void EnsureCapacity(int min) {
                if (_items.Length < min) {
                    int newCapacity = _items.Length == 0 
                        ? _defaultCapacity: _items.Length * 2;
                    //Array.MaxArrayLength long    
                    if ((uint)newCapacity > Array.MaxArrayLength) 
                        newCapacity = Array.MaxArrayLength;
                    if (newCapacity < min) newCapacity = min;
    
                    Capacity = newCapacity;
                }
            }
         //                       ,            
            public virtual int Capacity {
                get {
                    Contract.Ensures(Contract.Result<int>() >= Count);
                    return _items.Length;
                }
                set {
                    if (value < _size) {
                        throw new ArgumentOutOfRangeException("value", 
                            Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
                    }
                    Contract.Ensures(Capacity >= 0);
                    Contract.EndContractBlock();
    
                    if (value != _items.Length) {
                        if (value > 0) {
                            Object[] newItems = new Object[value];
                            if (_size > 0) { 
                                Array.Copy(_items, 0, newItems, 0, _size);
                            }
                            _items = newItems;
                        }
                        else {
                            _items = new Object[_defaultCapacity];
                        }
                    }            
                }
            }
    2. AddRange(ICollection):   ICollection      ArrayList    。         InsertRange(Int32, ICollection)  
    
        public virtual void AddRange(ICollection c) {
                InsertRange(_size, c);
            }
    3. Insert(Int32, Object)    :      ArrayList       。
    
        public virtual void Insert(int index, Object value) {
                if(index < 0 || index > _size)
                    throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_ArrayListInsert"));
                Contract.EndContractBlock();
    
                //    
                if(_size == _items.Length) EnsureCapacity(_size + 1);
    
                //        ,    ,           ,   Add         ,     
                if(index < _size){
                    Array.Copy(_items, index, _items, index + 1, _size - index);
                }
    
                _items[index] = value;
                _size++;
                _version++;
            }
    4. InsertRange(Int32, ICollection): ICollection        ArrayList       。
    
        public virtual void InsertRange(int index, ICollection c) {
                if (c==null)
                    throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection"));
                if (index < 0 || index > _size) 
                    throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
                Contract.EndContractBlock();//    
    
                int count = c.Count;//      ArrayList     
                if (count > 0) {
                    //      ,        
                    EnsureCapacity(_size + count);
                    //         ,                   
                    if (index < _size) {
                        //      
                        Array.Copy(_items, index, _items, index + count, _size - index);
                    }
    
                    //       for  ,               ?
                    //             ArrayList   
                    Object[] itemsToInsert = new Object[count];
                    c.CopyTo(itemsToInsert, 0);
                    //           
                    itemsToInsert.CopyTo(_items, index);
                    _size += count;
                    _version++;
                }
            }

    - 제거 요소: Remove (Object), RemoveAt (Int 32), RemoveRange (Int 32, Int 32), Clear ().
  • Remove (Object): ArrayList 에서 특정 대상 의 첫 번 째 일치 항목 을 제거 합 니 다.내부 에서 Index Of (Int 32) 와 RemoveAt (Int 32) 을 호출 했 습 니 다.
  •      public virtual void Remove(Object obj) {
                Contract.Ensures(Count >= 0);
    
                //  IndexOf(Int32)       
                int index = IndexOf(obj);
    
                if(index >= 0)
                    RemoveAt(index);
            }

    2. RemoveAt (Int 32): Array List 의 지정 한 색인 에 있 는 요 소 를 제거 합 니 다.
         public virtual void RemoveAt(int index) {
                if (index < 0 || index >= _size) 
                    throw new ArgumentOutOfRangeException("index", 
                    Environment.GetResourceString("ArgumentOutOfRange_Index"));
                Contract.Ensures(Count >= 0);
                Contract.EndContractBlock();
    
                _size--;//    ,    1
                //               ,      
                if (index < _size) {
                    Array.Copy(_items, index + 1, _items, index, _size - index);
                }
                _items[_size] = null;
                _version++;
            }

    3. RemoveRange (Int 32, Int 32): Array List 에서 일정한 범위 의 요 소 를 제거 합 니 다.
         public virtual void Clear() {
                if (_size > 0)
                {
                    //     
                    Array.Clear(_items, 0, _size);
                    _size = 0;
                }
                _version++;
            }

    - 정렬: Sort (), Sort (IComparer), Sort (Int 32, Int 32, IComparer), Reverse (), Reverse (Int 32, Int 32)
  • Sort (): 전체 Array List 의 요 소 를 정렬 합 니 다.Array List 의 정렬 방법 은 모두 내부 에서 Sort (Int 32, Int 32, IComparer) 를 호출 하여 정렬 합 니 다.
  • Sort (IComparer): 지정 한 비교 기 를 사용 하여 전체 Array List 의 요 소 를 정렬 합 니 다.
  • Sort (Int 32, Int 32, IComparer): 지정 한 비교 기 를 사용 하여 Array List 의 한 범위 내 요 소 를 정렬 합 니 다.
  •      public virtual void Sort(int index, int count, IComparer comparer) {
                if (index < 0)
                    throw new ArgumentOutOfRangeException("index", 
                    Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
                if (count < 0)
                    throw new ArgumentOutOfRangeException("count", 
                    Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
                if (_size - index < count)
                    throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
                Contract.EndContractBlock();
    
                //         
                Array.Sort(_items, index, count, comparer);
                _version++;
            }

    4. Reverse (): 전체 Array List 에서 요소 의 순 서 를 반전 시 킵 니 다.
         public virtual void Reverse(int index, int count) {
                if (index < 0)
                    throw new ArgumentOutOfRangeException("index", 
                    Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
                if (count < 0)
                    throw new ArgumentOutOfRangeException("count", 
                    Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
                if (_size - index < count)
                    throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
                Contract.EndContractBlock();
    
                Array.Reverse(_items, index, count);
                _version++;
            }

    5. Reverse (Int 32, Int 32): 지정 한 범위 의 요소 의 순 서 를 반전 합 니 다.
         public virtual void Reverse(int index, int count) {
                if (index < 0)
                    throw new ArgumentOutOfRangeException("index", 
                Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
                if (count < 0)
                    throw new ArgumentOutOfRangeException("count", 
                Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
                if (_size - index < count)
                    throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
                Contract.EndContractBlock();
    
                Array.Reverse(_items, index, count);
                _version++;
            }

    ArrayList 는 C \ # 에서 가장 간단 한 데이터 구조 라 고 할 수 있 습 니 다. ArrayList 를 사용 할 때 일부 성능 향상 을 얻 기 위해 예측 가능 한 용량 크기 범위 내 에서 고정된 초기 용량 을 사용 하여 ArrayList 를 구축 하여 특정한 상황 에서 내부 배열 의 중복 생 성과 데이터 위치의 변 화 를 피 할 수 있 습 니 다.

    좋은 웹페이지 즐겨찾기