기본 Arraylist는 동적 배열을 유지하고 각 ArrayList 인스턴스에는 용량이 있습니다. 이 용량은 목록 요소를 저장하는 데 사용되는 배열의 크기를 나타냅니다. 항상 목록의 크기와 동일합니다. 요소가 Arraylist에 지속적으로 추가되면 용량도 자동으로 증가합니다.
ArrayList는 동기식이 아닙니다 (즉, 스레드 안전이 아님). 여러 스레드가 ArrayList 인스턴스에 동시에 액세스하고 적어도 하나의 스레드가 목록을 구조적으로 수정하면 외부 동기화를 유지해야합니다. 다중 스레드 환경에서는 컬렉션을 사용하여 스레드-안전 배열 목록을 선언 할 수 있습니다.
목록 ArrayList = collections.SynChronizedList (new ArrayList ());
다음은 원리를 분석하기위한 ArrayList의 소스 코드입니다.
1. Arraylist Construction 방법 : Arraylist는 세 가지 다른 시공 방법을 제공합니다.
1) ArrayList ()는 초기 용량이 10 인 빈 목록을 구성합니다.
2) 지정된 초기 용량의 빈 목록을 구성하는 ArrayList (int initialcapacity).
3) ArrayList (Collection <? extends e> c), 지정된 컬렉션이 포함 된 요소 목록을 구성하며, 이는 컬렉션의 반복자가 반환하는 순서로 배열됩니다.
소스 코드는 다음과 같습니다.
개인 과도 객체 [] elementData; public arraylist (int initialcapacity) {super (); if (InitialCapacity <0) New ImperalArgumentException을 던지십시오 ( "불법 용량 :"+ 초기 범위); this.elementData = 새 개체 [초기 커피 션]; // 길이의 객체 유형 생성 길이 10} public arraylist () {this (10); // call arraylist (int i)} <br> <br> public arraylist (collection <? extends e> c) {elementData = c.toArray (); //이 컬렉션의 모든 요소가 포함 된 배열을 반환 크기 크기 = ElementData.length; // c.toArray는 (잘못된) return object [] (6260652 참조) if (elementData.getClass ()! = Object []. class) emEctData = arrays.copyof (ElementData, size, object []. class); // 지정된 배열을 복사하고 동일한 요소와 길이를 포함하는 객체 유형 배열을 반환}} ArrayList ()를 사용하여 매개 변수가없는 컬렉션 객체를 생성 할 때, ArrayList (int initialCapacity) 생성자는 바닥에서 호출되어 길이 10을 갖는 객체 유형의 배열을 생성합니다. 세트 유형 매개 변수가있는 생성자를 사용하면 동일한 요소와 길이를 포함하는 객체 유형의 배열이 바닥에 생성됩니다.
2. 메소드 추가 : ArrayList는 요소를 추가 할 두 가지 추가 메소드를 제공합니다.
1) 추가 (e e)를 추가하고 지정된 요소를이 목록의 끝에 추가하십시오.
2) 추가 (int index, e e)를 추가하고 지정된 요소를이 목록의 지정된 위치에 삽입하십시오. 현재 해당 위치 (있는 경우) 및 모든 후속 요소 (1에 의해 색인)에있는 요소를 오른쪽으로 이동하십시오.
public boolean add (e e) {ensurecapacity (size + 1); // 배열 용량 확장 요소 data [size ++] = e; // 첨자 크기로 객체 배열에 요소 e를 추가하고 size ++를 실행합니다. } public void add (int index, e element) {if (index> size || index <0) // 삽입 될 지정된 배열 위시가 배열 용량을 초과하거나 지정된 첨자가 0보다 작 으면 새로운 indexoutofBoundsexception ( "index :"+index+", size); ensurecapacity (size+1); // 배열 용량 시스템 확장. ArrayCopy (ElementData, Index, ElementData, Index + 1, Size -Index); // 지정된 소스 배열에서 배열을 복사하면 사본이 지정된 위치에서 대상 배열의 지정된 위치로 시작됩니다. <br> // elementData --- 소스 배열 인덱스 --- 소스 배열에서 시작 위치 <br> // elementData --- 대상 배열 index+1 --- 대상 배열에서 시작 위치 <br> // size-index --- 복사 할 배열 요소 [index] = element; // 지정된 배열 인덱스 크기 ++에 추가 할 요소를 넣습니다. } 공개 void ensurecapacity (int mincapacity) {modcount ++; int OldCapacity = ElementData.length; // 원래 배열의 용량 if (minCapacity> OldCapacity) {Object OldData [] = ElementData; int newCapacity = (OldCapacity * 3)/2 + 1; // 새로운 배열의 용량을 정의하는데, 이는 원래 배열의 용량의 1.5 배인 용량 +1 if (newCapacity <mincapacity) newCapacity = mincapacity; // mincapacity는 일반적으로 크기에 가깝기 때문에 이것은 다음과 같습니다. elementData = arrays.copyof (elementData, newCapacity); // 지정된 배열을 복사하고 새 배열의 용량을 newCapacity}}}}} 컬렉션에 10 개 이상의 요소가 추가되면 Arraylist 하단 레이어는 원래 배열의 1.5 배 + 1의 길이를 가진 새 배열을 생성하고 원래 배열의 요소를 새 배열로 복사하고 후속 추가 요소가 새 배열에 배치됩니다. 이 프로세스는 새 배열의 길이가 새로 추가 된 요소를 수용 할 수없는 경우 반복됩니다. 이것이 컬렉션에 요소를 추가하는 구현 원리입니다.
3. 방법 GET :
1) get (int index),이 목록의 지정된 위치에서 요소를 반환하십시오.
public e get (int index) {rangecheck (index); // 통과 된 지정된 인덱스가 법적 반환인지 확인하십시오 (e) ElementData [index]; // 배열 위시 색인 index}로 배열 요소를 반환하십시오} private void rangecheck (int index) {if (index> = size) // 세트의 용량보다 크거나 같은 경우 새로운 indexoutofBoundsexception ( "index :"+index+", size); } 4. 방법 제거 :
1) e 제거 (int index),이 목록의 지정된 위치에서 요소를 제거하십시오. 모든 후속 요소를 왼쪽으로 이동하십시오 (지수의 감소 1).
2) 부울 제거 (Object O),이 목록에 처음으로 나타나는 지정된 요소를 제거하십시오 (현재). 목록 에이 요소가 포함되어 있지 않으면 목록이 변경되지 않고 부울 값이 반환됩니다.
public e remove (int index) {rangecheck (index); // 지정된 색인이 법적 modcount ++인지 확인하십시오. e OldValue = (e) ElementData [index]; // 지정된 색인의 배열 요소를 가져옵니다 int nummoved = size -1; // 이동할 요소 수 (NumMoved> 0) System.ArrayCopy (ElementData, Index+1, ElementData, Index, Nummoved); // 배열 요소 elementData를 움직입니다 [-size] = null; // GC가 작업을 수행하도록하자 OldValue를 반환합니다. } public boolean remove (object o) {if (o == null) {// 전달 된 매개 변수가 (int index = 0; index <size; index ++) if (elementData [index] == null) {// null fastremove (index)의 첫 번째 발생을 제거합니다. 진실을 반환하십시오. }} else {for (int index = 0; index <size; index ++) if (o.equals (elementData [index]) {fastremove (index); 진실을 반환하십시오. }} 거짓을 반환합니다. } private void fastremove (int index) {// 지정된 위치에서 요소를 제거하면 구현 방법은 제거 (int i) modcount ++; int nummoved = size -index -1; if (nummoved> 0) System.arrayCopy (ElementData, index+1, elementData, index, nummoved); ElementData [-size] = null; // GC가 작동하도록하자} 5. 클론 방법 :
1) Object Clone () 은이 ArrayList 인스턴스의 얕은 사본을 반환합니다 (이 요소 자체를 복사하지 않음).
public object clone () {try {arraylist <e> v = (arraylist <e>) super.clone (); // arraylist 객체를 반환하기 위해 객체 클래스의 클론 메소드 계산 v.elementData = arrays.copyof (elementData, size); // 대상 배열을 복사 v.modCount = 0; 반환 v; } catch (clonenotsupportedException e) {// 복제 할 수 있기 때문에 새로운 internalError (); }} ArrayList의 일부 주요 소스 코드에 대한 위의 분석은 ArrayList의 기본 구현 원리를 알고 있습니다. ArrayList 소스 코드에는 다음과 같은 점과 점이 있습니다.
1) 배열 목록의 기본 계층은 배열에 따라 구현되며, 대상 요소는 다음 표준을 통해 정확하게 찾을 수 있으므로 검색 효율이 높습니다. 그러나 요소를 추가하거나 삭제하는 데는 비효율적 인 많은 요소의 위치 이동이 포함됩니다.
2) ArrayList는 세 가지 다른 시공 방법을 제공합니다. 매개 변수가없는 구조 방법은 하단 레이어에서 기본적으로 길이가 10 인 객체 유형의 배열을 생성합니다. 세트에 추가 된 요소 수가 10보다 클 때 배열은 자동으로 확장됩니다. 즉, 새 배열을 생성하고 원래 배열의 요소를 새 배열에 배치합니다.
3) ensurecapacity 메소드는 배열을 확장하여 원래 배열의 1.5 배 + 1의 길이를 생성합니다. 요소가 Arraylist에 지속적으로 추가되므로 배열 길이가 요구 사항을 충족 할 수없는 경우 프로세스를 반복하십시오.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.