ArrayList를, LinkedList의, 벡터,으로 CopyOnWriteArrayList 차이 및 소스 코드 분석

1. ArrayList를

ArrayList를 큐에 대응하는 배열 인 동적 배열 . 배열의 자바에 비해 그 용량은 동적으로 성장할 수 있습니다 . 그것은 AbstractList를 구현 목록 가능해, RandomAccess, Cloneable을, java.io.Serializable을에게 이러한 인터페이스를 상속합니다. 기본 크기는 10 (소스로부터 알 수 1.5 배 각각 팽창 용량 , INT newCapacity oldCapacity = + (oldCapacity >> 1)). ArrayList에에서 작동 스레드로부터 안전하지 않습니다! 그래서, 하나의 스레드에서의 ArrayList를 사용하는 경우에만 권장 하고,에 여러 스레드 벡터 또는으로 CopyOnWriteArrayList를 선택할 수 있습니다 .

공공  클래스 의 ArrayList <E가> 확장 AbstractList를 <E>
         구현 목록을 <E> , 가능해, RandomAccess, Cloneable을, java.io.Serializable을 
{ 
    ... 
    
    / ** 
     * 초기 용량은 기본. 
     * / 
    개인  정적  최종  INT의 DEFAULT_CAPACITY = 10 ; 

    공공 의 ArrayList ( INT의 파라미터 : initialCapacity) {
         경우 (파라미터 : initialCapacity> 0 ) {
              .elementData = 새로운 개체 [파라미터 : initialCapacity]; 
        } 다른  경우 (파라미터 : initialCapacity == 0) {
              .elementData는 = EMPTY_ELEMENTDATA는; 
        } 다른 {
             던져  새로운 IllegalArgumentException가 ( "잘못된 용량 :"+ 
                                               파라미터 : initialCapacity)를; 
        } 
    }     
    
    공공 의 ArrayList () {
          .elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; 
    } 
    
    공공 ArrayList를 (컬렉션 <? 확장 E> c)를 { 
        ...... 
    } 

    개인  무효 성장한다 ( INT minCapacity가) {
             //오버플 민감한 코드 
            INT oldCapacity = elementData.length;
            INT newCapacity oldCapacity = + (oldCapacity >> 1 );
            경우 (newCapacity - minCapacity가 <0 ) 
                    newCapacity = minCapacity가;
            경우 (newCapacity - MAX_ARRAY_SIZE> 0 ) 
                    newCapacity = hugeCapacity (minCapacity가);
            // 이 승리 그래서 minCapacity가은, 일반적으로 가까운 크기이다 
            으로부터 elementData = Arrays.copyOf (으로부터 elementData, newCapacity이); 
        } 

    공공  INT의 크기 () {
        반환 크기; 
    } 

       ... 
}

1.1 ArrayList를 확대

코드 수로부터 팽창, 각 확장은 1.5 배 증가 제 소자 (11)의 의지에 삽입 할 때의 ArrayList 기본 용량은 10 int newCapacity = oldCapacity + (oldCapacity >> 1);알.

2. LinkedList의

로 ArrayList를하고 LinkedList의는 List 인터페이스를 구현하지만, LinkedList의는 이중 연결리스트의 구현입니다.

공공  클래스 LinkedList의가 <E가>
     확장 아니고 AbstractSequentialList <E>
     구현 목록 <E>를 Deque와 <E> , Cloneable을, java.io.Serializable을 
{ 
       과도  INT의 크기 = 0 ; 

    과도 노드 <E> 제; 

    과도 노드 <E> 마지막; 

    공개 LinkedList의 () { 
        } 

    개인  정적  클래스 노드 <E> { 
            E 항목; 
            노드 <E> 다음; 
            노드 <E> 이전; 

        노드 (노드 <E> 이전, E 원소, 노드 <다음) {
              .item = 요소;
                     다음 내용은 = 다음;
                     .prev = 이전; 
                } 
        } 

    ... 
}

2.1의 ArrayList와 LinkedList의 차이점

  • 순회 루프, Foreach 루프, 반복자 인터페이스에 보통 사용할 수 있습니다
  • 어레이의 실현에 기초 ArrayList를, LinkedList의 기반 이중 연결리스트
  • 랜덤 액세스 및 수정 ArrayList와 효율이 비교적 높은 LinkedList의 삽입 및 삭제의 효율적이고

3. 벡터

벡터는 스레드 안전 동기화의 많은 소스 코드에서 볼 수있다. 벡터, 거의 모든 훨씬 더 큰 읽기 쓰기 작업 시나리오에 비해 외부 노출의 방법 동적 배열 스레드 안전 자바 이전의 제공, 동기 키워드를 수정하고, 벡터 시스템에 성능 오버 헤드로 이어지는 잠금 경합이 많이 발생합니다. 기록을 위해이 장면의 독서보다 더 크다 .

공공  클래스 벡터 <E> 키
     확장 AbstractList를 <E>
     구현 목록 <E> , 가능해, RandomAccess, Cloneable을, java.io.Serializable을 
{ 
    ... 
    보호 객체 []으로부터 elementData을;
    보호  하는 int 에 elementCount;
    보호  하는 int capacityIncrement 만; 

    공공 벡터 ( INT의 파라미터 : initialCapacity) {
              (파라미터 : initialCapacity, 0 ); 
    } 

    공공 벡터 () {
              (10 ); 
        } 
    
    공공  동기  INT용량 () {
             반환 elementData.length 단계; 
        } 

    공공  동기  INT의 크기는 () {
             반환 에 elementCount를; 
        } 
    ... 
}

ArrayList를하고 벡터의 차이

 

  • 벡터는 스레드 안전 , 동기화 된 소스 코드를 많이 볼 수 있지만, 거기에 ArrayList를하지 . 그래서 ArrayList를 벡터 높은 성능보다, 하나의 스레드 .
  • 사용되는 연속적인 메모리 어레이의 ArrayList와 기저 벡터, 용량이 필요한 충분한 저장 공간이 ArrayList를 디폴트는 1.5 배 증가, 벡터가 2 배로 증가 원래 디폴트 ;
  • 사용되는 시간의 ArrayList와 벡터가 동일하며, 지정된 위치 데이터를 찾기 그들은 0이다 (1) 벡터의 ArrayList와 캔을 이용하여 이번에

 

4.으로 CopyOnWriteArrayList

으로 CopyOnWriteArrayList는 다음과 같은 특징이 있습니다 :

  • 구현 목록 인터페이스;
  • ) (A ReentrantLock와 잠금 장치 내부 = 새로운 ReentrantLock와를 보유;
  • 어레이 증가의 새 복사본이 삽입이 완료 변형 또는 새로운 어레이 배열에 할당 된 동작 후에 제거된다 ;
  • 추가 및 삭제가 잠금을 확보하는 데 필요한, 단 잠금 및 읽기 잠금을 얻을 필요가 없습니다되어, 동시 지원합니다 . 왜 원래 견적 작업이 완료된 후, 새로운 배열을 만든 다음 할당 할 필요성을 추가 및 삭제? 이것은 당신이 데이터를 얻을 수행 읽기 작동을 일으킬 수있는 추가 및 삭제의 과정에서 직접 원래 배열을 수정하면, 요소에 얻을 수있는 시간을 얻을 수 있도록하는 것입니다;
  • ReentrantLock와 내부 스레드 안전을 보장;

방법으로 CopyOnWriteArrayList java.util.concurrent의 패키지가 구현되는, 제공되는 잠금없이 판독 동작은 , 기입 동작 기본 배열 조작함으로써 새로운 복사 하는 달성되는 별도의 읽기 및 쓰기 동시성 전략

그 원칙은 이후 추가, 설정, 삭제와 같은 수정 작업은, 원래의 배열을 복사합니다 원래 배열, 다른 스레드 안전을 달성하기 위해 이러한 방어 방법을 수정 바꾸기 때문이다 CopyOnWrite.

이 데이터 구조 그래서, 읽기 및 운영을 작성하거나 비용이 여전히 매우 분명하다 수정 상대적으로 덜 적합 쓰기 장면보다 훨씬 더 읽기에 적합합니다 .

공개  수업 으로 CopyOnWriteArrayList <E>
     구현 목록 <E> , 가능해, RandomAccess, Cloneable을, java.io.Serializable을 {
         개인  정적  최종  오래 serialVersionUID의 = 8673264195747942595L ; 
    
    / ** 모든 뮤 테이터 보호 잠금 * / 
    최종  순간의 ReentrantLock와 잠금 = 새로운 ReentrantLock와를 (); 
    
    / ** 만의 getArray / setArray 통해 액세스하는 어레이. * / 
    개인  과도  휘발성 개체 [] 배열; 

    공공  부울 추가 (E 전자) {
             최종 ReentrantLock와 잠금 =.lock; 
            () lock.lock; 
            시도 { 
                개체 [] 엘리먼트 = 의 getArray을 ();
                INT LEN = elements.length; 
                개체 []를 newElements = Arrays.copyOf (요소 렌 + 1 ); 
                newElements에 [LEN] = E; 
                setArray (newElements에); 
                반환  사실 ; 
            } 마지막 { 
                ) (lock.unlock; 
            } 
        } 
    
    } 

    ... 
}

 

추천

출처www.cnblogs.com/windpoplar/p/11886116.html