자바 기반 - ArrayList 소스 분석

15838 단어 자바ArrayList
더 많은 자바 집합 글, 제 블 로그 에 주목 하 세 요:http://blog.csdn.net/qq_30379689
자바 기반 - ArrayList 소스 분석
이 글 은 다음 과 같은 내용 을 포함 하고 있 습 니 다. 왼쪽 상단 + 번 호 를 클릭 하여 디 렉 터 리 를 펼 치 십시오.
  • Array List 가 무엇 입 니까
  • ArrayList 의 구조 함수
  • ArrayList 의 저장 소
  • ArrayList 읽 기
  • ArrayList 삭제
  • ArrayList 배열 용량 조정
  • ArrayListFail - Fast 메커니즘
  • 총화
  • 1. Array List 가 무엇 입 니까?
  • Array List 는 동적 배열 로 이해 할 수 있 는데 그 용량 은 동적 으로 증가 할 수 있다. 이 용량 은 목록 요 소 를 저장 하 는 배열 의 크기 를 말 하 는데 Array List 에 요 소 를 계속 추가 하면 서 그 용량 도 자동 으로 증가한다
  • .
  • ArrayList 는 null 을 포함 한 모든 요 소 를 허용 합 니 다
  • ArrayList 는 List 인터페이스의 비동기 실현
  • ArrayList 는 질서 가 있다
  • 메모: 자동 성장 은 데 이 터 를 새 배열 로 재 복사 할 수 있 습 니 다. 따라서 데이터 의 양 을 예측 할 수 있 으 면 Array List 를 구성 할 때 용량 을 지정 할 수 있 습 니 다.대량의 요 소 를 추가 하기 전에 응용 프로그램 도 ensureCapacity 작업 을 사용 하여 ArrayList 인 스 턴 스 의 용량 을 증가 시 킬 수 있 습 니 다. 이것 은 증가 식 재분배 의 수량 을 줄 일 수 있 습 니 다.
    public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    
    }
  • ArrayList 는 List 인터페이스, 바 텀 에서 배열 로 모든 요 소 를 저장 하 는 것 을 실현 했다. 그 조작 은 대체적으로 배열 에 대한 조작
  • 이다.
  • ArrayList 는 AbstractList 추상 류 를 계승 하여 배열 대기 열 로 관련 추가, 삭제, 수정, 옮 겨 다 니 는 기능
  • 을 제공 합 니 다.
  • ArrayList 는 RandmoAccess 인 터 페 이 스 를 실현 했다. 즉, 랜 덤 액세스 기능 을 제공 했다. RandmoAccess 는 자바 에서 List 에 의 해 실현 되 고 List 에 빠 른 접근 기능 을 제공 하 는 것 이다. 우 리 는 요소 의 번 호 를 통 해 요소 대상 을 신속하게 얻 을 수 있다. 이것 이 바로 빠 른 랜 덤 액세스
  • 이다.
  • ArrayList 는 Cloneable 인 터 페 이 스 를 실현 했다. 즉, 함수 clone () 을 덮어 복제 할 수 있다
  • .
  • ArrayList 는 자바. io. Serializable 인 터 페 이 스 를 실현 하여 ArrayList 지원 직렬 화
  • 를 의미 합 니 다.
    2. Array List 의 구조 함수
    Array List 는 세 가지 방식 의 구조 기 를 제공 합 니 다.
  • Public Array List (): 기본 초기 용량 이 10 인 빈 목록 을 만 들 수 있 습 니 다
  • Public ArrayList (int initialCapacity): 초기 용량 을 지정 한 빈 목록 을 만 듭 니 다
  • Public Array List (Collection c): 지정 한 collection 요 소 를 포함 하 는 목록 을 구성 합 니 다. 이 요 소 는 이 collection 의 교체 기 에 따라 순서대로 배열 되 어 있 습 니 다
  • .
    private transient Object[] elementData;
    
    public ArrayList() {
        this(10);
    }
    
    public ArrayList(int initialCapacity) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
    }
    
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        size = elementData.length;
    
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    }

    3. Array List 의 저장 소
    1、set(int index, E element)
    이 방법 은 먼저 range Check (index) 을 호출 하여 index 변수 가 배열 범 위 를 초과 하 는 지 확인 하고 초과 하면 이상 을 던 집 니 다. 초과 하지 않 으 면 원래 index 위치의 값 을 꺼 내 고 새로운 element 를 index 위치 에 넣 고 oldValue 로 돌아 갑 니 다.
    public E set(int index, E element) {
        rangeCheck(index);
    
        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }
    
    private void rangeCheck(int index) {
      if (index >= size)
      throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    2、add(E e)
    이 방법 은 지정 한 요 소 를 목록 의 끝 에 추가 하 는 것 입 니 다. 용량 이 부족 할 때 grow 방법 으로 용량 을 늘 립 니 다.
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    private void ensureCapacityInternal(int minCapacity) {
        modCount++;
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    3、add(int index, E element)
    index 위치 에 element 삽입
    public void add(int index, E element) {
        rangeCheckForAdd(index);
    
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

    4, addAll (Collection c) 와 addAll (int index, Collection c)
    특정 Collection 의 요 소 를 Arraylist 끝 에 추가 합 니 다.
    public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }
    
    public boolean addAll(int index, Collection<? extends E> c) {
        rangeCheckForAdd(index);
    
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount
    
        int numMoved = size - index;
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,
                             numMoved);
    
        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
    }

    4. Array List 의 읽 기
    Array List 가 무 작위 접근 을 지원 할 수 있 는 이 유 는 분명 하 다. 내부 의 데이터 구 조 는 배열 이 고 배열 자체 가 무 작위 접근 을 지원 하기 때문이다. 이 방법 은 먼저 입력 한 index 값 이 경 계 를 넘 었 는 지 판단 한 다음 에 배열 의 index 위치 요 소 를 되 돌려 주면 된다.
    public E get(int index) {
        rangeCheck(index);
        return (E) elementData[index];
    }
    private void rangeCheck(int index) {
        if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    5. Array List 의 삭제
    ArrayList 는 아래 표 시 를 하거나 지정 한 대상 에 따라 두 가지 방식 으로 삭제 하 는 기능 을 제공 합 니 다. 주의해 야 할 것 은 배열 에서 요 소 를 제거 하 는 작업 도 제 거 된 요소 이후 의 모든 요 소 를 왼쪽으로 이동 시 킬 수 있 습 니 다.
  • 배열 의 index 위치 에 있 는 요 소 를 삭제 합 니 다
  • 배열 에서 같은 대상 의 요 소 를 삭제 합 니 다
  • public E remove(int index) {
        rangeCheck(index);
    
        modCount++;
        E oldValue = elementData(index);
    
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // Let gc do its work
    
        return oldValue;
    }
    
    public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }

    6. ArrayList 배열 용량 조정
    위 에서 소개 한 Array List 에 요 소 를 저장 하 는 코드 에서 우 리 는 배열 에 요 소 를 추가 할 때마다 추 가 된 요소 의 개수 가 현재 배열 의 길 이 를 초과 하 는 지 확인 해 야 한다. 초과 하면 배열 은 확장 하여 데 이 터 를 추가 하 는 수 요 를 만족 시 킬 것 이다.
    배열 확장 은 두 가지 방법 이 있 습 니 다. 그 중에서 개발 자 는 하나의 Public 방법 으로 ensureCapacity (int minCapacity) 를 통 해 Array List 의 용량 을 증가 시 킬 수 있 습 니 다. 저장 요소 등 작업 과정 에서 용량 이 부족 하면 priavte 방법 private void ensureCapacity Internal (int minCapacity) 을 호출 하여 실현 합 니 다.
    public void ensureCapacity(int minCapacity) {
        if (minCapacity > 0)
            ensureCapacityInternal(minCapacity);
    }
    
    private void ensureCapacityInternal(int minCapacity) {
        modCount++;
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    상기 코드 에서 알 수 있 듯 이 배열 을 확대 할 때 오래된 배열 의 요 소 를 새로운 배열 로 다시 복사 합 니 다. 매번 배열 의 용량 증 가 는 원래 용량 의 1.5 배 (int new Capacity = oldCapacity + (oldCapacity > > 1) 코드 에서 나 온 것 입 니 다. 이런 작업 의 대 가 는 매우 높 기 때문에 실제 사용 할 때...우 리 는 가능 한 한 배열 용량 의 확장 을 피해 야 한다.저장 할 요소 의 많 고 적 음 을 예측 할 수 있 을 때, ArrayList 인 스 턴 스 를 구성 할 때, 배열 확장 이 발생 하지 않도록 용량 을 지정 하거나, 실제 수요 에 따라 ensureCapacity 방법 을 호출 하여 ArrayList 인 스 턴 스 의 용량 을 수 동 으로 증가 시 킵 니 다.
    7. ArrayListFail - Fast 메커니즘
    Array List 도 빠 른 실패 체 제 를 사용 하여 modCount 인 자 를 기록 함으로써 이 루어 집 니 다. 동시 다발 적 인 수정 에 직면 할 때 교체 기 는 곧 완전히 실패 할 것 입 니 다. 앞으로 특정한 불확실 한 시간 에 임 의적 으로 불확실 한 행위 가 발생 할 위험 을 무릅 쓰 는 것 이 아 닙 니 다.Fail - Fast 에 대한 소 개 는 제 이전의 HashMap 의 글 자바 기초 인 HashMap 의 상세 한 해석 과 면접 문제 풀이 를 볼 수 있 습 니 다
    8. 총화
    전에 배 운 내용 과 오늘 배 운 내용 을 복습 하고 그림 으로 말 하 세 요.

    좋은 웹페이지 즐겨찾기