>  기사  >  Java  >  Java 수집 프레임워크 ArrayList 소스 코드 상세 분석(그림)

Java 수집 프레임워크 ArrayList 소스 코드 상세 분석(그림)

黄舟
黄舟원래의
2017-03-28 10:55:141579검색

전체 소개

ArrayList는 요소가 있는 순차 컨테이너인 List 인터페이스를 구현합니다. 저장 데이터는 넣은 순서와 동일하므로 null 요소를 넣을 수 있습니다. 기본 레이어는 배열을 통해 을 구현합니다. 이 클래스가 동기화를 구현하지 않는다는 점을 제외하면 나머지는 Vector와 거의 동일합니다. 각 ArrayList에는 기본 배열의 실제 크기를 나타내는 용량이 있습니다. 컨테이너에 저장된 요소 수는 현재 용량을 초과할 수 없습니다. 요소가 컨테이너에 추가되면 용량이 부족하면 컨테이너가 기본 배열의 크기를 자동으로 늘립니다. 앞서 언급했듯이 Java 제네릭은 컴파일러에서 제공하는 구문 설탕일 뿐이므로 여기서 배열은 모든 유형의 Object를 수용할 수 있는 Object 배열입니다.

Java 수집 프레임워크 ArrayList 소스 코드 상세 분석(그림)

size(), isEmpty(), get() 및 set() 메소드는 모두 일정한 시간에 완료될 수 있습니다. add() 메소드의 시간 비용은 다음과 같습니다. 삽입 위치와 관련하여 addAll() 메서드의 시간 비용은 추가된 요소 수에 비례합니다. 다른 방법의 대부분은 선형 시간입니다.

효율성을 추구하기 위해 ArrayList는 동기화되지 않습니다. 여러 스레드의 동시 액세스가 필요한 경우 사용자가 수동으로 동기화하거나 대신 Vector를 사용할 수 있습니다.

메서드 분석

set()

하단 레이어는 배열이므로 ArrayListset() 메소드는 매우 간단해지기 때문에 직접 배열 지정된 위치에 값을 할당하면 됩니다.

public E set(int index, E element) {
    rangeCheck(index);//下标越界检查
    E oldValue = elementData(index);
    elementData[index] = element;//赋值到指定位置,复制的仅仅是引用
    return oldValue;
}

get()

get() 메서드도 매우 간단합니다. 주의할 점은 기본 배열이 Object[]이므로 유형을 수행해야 한다는 것입니다. 요소를 가져온 후 변환 .

public E get(int index) {
    rangeCheck(index);
    return (E) elementData[index];//注意类型转换
}

add()

는 C++의 벡터와 다르며, ArrayList에는 bush_back() 메서드가 없으며 해당 메서드는 add(E e), ArrayList에도 insert() 메서드가 없으며 해당 메서드는 add(int index, E e)입니다. 두 방법 모두 컨테이너에 새로운 요소를 추가하므로 용량이 부족할 수 있으므로 요소를 추가하기 전에 남은 공간을 확인하고 필요한 경우 자동으로 확장해야 합니다. grow() 메소드를 통해 최종적으로 확장 작업이 완료됩니다.

private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);//原来的3倍
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);//扩展空间并复制
}

Java GC는 메모리를 자동으로 관리하므로 여기서는 소스 배열 릴리스 문제를 고려할 필요가 없습니다.

Java 수집 프레임워크 ArrayList 소스 코드 상세 분석(그림)

공간 문제가 해결되고 나면 삽입 과정이 매우 간단해집니다.

Java 수집 프레임워크 ArrayList 소스 코드 상세 분석(그림)

add(int index, E e)요소를 먼저 이동한 후 삽입 작업을 완료해야 하므로 이 방법은 선형 시간 복잡도를 갖습니다.

addAll()

addAll() 메서드는 한 번에 여러 요소를 추가할 수 있습니다. 위치에 따라 두 개의 핸들이 있습니다. 하나는 addAll(Collection 확장<code>addAll(Collection <a href="http://www.php.cn/wiki/166.html" target="_blank">extends</a> E> c) E> c) 메소드, 지정된 위치에서 하나 삽입addAll(int index, Collection extends E> c)메소드 . add() 방법과 마찬가지로 삽입 전 공백 확인도 필요하며, 필요한 경우 자동으로 용량이 확장되며, 지정된 위치부터 삽입하면 요소가 이동될 수도 있습니다.
addAll()의 시간 복잡도는 삽입된 요소의 수뿐만 아니라 삽입 위치와도 관련이 있습니다.

remove()

remove() 메소드에도 두 가지 버전이 있습니다. 하나는 지정된 위치의 요소를 삭제하는 remove(int index)이고 다른 하나는 첫 번째 요소를 삭제하는 remove(Object o)입니다. o.equals(elementData[index]) 요소를 만족합니다. 삭제 작업은 add() 작업의 역과정으로, 삭제 지점 이후의 요소를 한 위치 앞으로 이동해야 합니다. GC가 작동하려면 마지막 위치에 null 값이 명시적으로 할당되어야 한다는 점에 유의해야 합니다.

아아아아

위 내용은 Java 수집 프레임워크 ArrayList 소스 코드 상세 분석(그림)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.