Array List 입문 부터 입 토 까지

ArratList 입문 부터 입 토 까지
기본 소개
상속 도
한 가지 유형 을 알 고 싶다 면 먼저 상속 관 계 를 살 펴 보 자.
[외부 체인 이미지 전송 에 실 패 했 습 니 다. 원본 사이트 에 도 난 방지 체인 체제 가 있 을 수 있 습 니 다. 그림 을 저장 하여 직접 업로드 하 는 것 을 권장 합 니 다 (img - JN0kmlbq - 159738587026) (https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200729104158.png)]

기본 소개
  • 무 작위 접근 속도 가 빠 르 고 삽입 과 제거 성능 이 떨어진다
  • 요소 중복 및 null
  • 지원
  • 원 소 는 순서 가 있다
  • 라인 이 안전 하지 않 음
  • 배열 의 크기 를 유연 하 게 조정
  • Array List 는 동적 배열 을 바탕 으로 이 루어 진 것 으로 삭제 할 때 배열 의 복사 복사 복사
  • 가 필요 하 다.
  • Array List 의 기본 초기 화 용량 은 10. 확장 할 때마다 원래 용량 의 절반 을 늘 리 는 것, 즉 원래 의 1.5 배
  • 로 변 하 는 것 이다.
  • 요 소 를 삭제 할 때 용량 을 줄 이지 않 고 용량 을 줄 이려 면 trimToSize ()
  • 를 호출 합 니 다.
  • iterator 를 사용 하면 다 중 스 레 드 이상
  • 을 일 으 킬 수 있 습 니 다.
    ArrayList<String> alist = new ArrayList<String>();
    

    ArrayList 가 List 인 터 페 이 스 를 실현 하기 때문에 alist 변수의 유형 은 list 형식 일 수 있 습 니 다.new 키워드 성명 후의 뾰족 한 괄호 에서 도 요소 의 종 류 를 지정 하지 않 아 도 됩 니 다.
    RandomoAccess 인터페이스, 즉 무 작위 접근 기능 을 제공 하기 때문이다.우 리 는 원소 의 수 요 를 통 해 원소 의 대상 을 신속하게 얻 을 수 있다.
    Cloneable 인 터 페 이 스 를 실 현 했 기 때문에 함수 clone () 이 복 제 될 수 있 습 니 다.
    Serializable 인터페이스 가 실현 되 었 기 때문에 직렬 화 를 지원 하고 직렬 화 를 통 해 데 이 터 를 전송 할 수 있 음 을 의미 합 니 다.
    기본 속성
    public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable {  
        // 序列化id  
        private static final long serialVersionUID = 8683452581122892189L;  
        // 默认初始的容量  
        private static final int DEFAULT_CAPACITY = 10;  
        // 一个空对象(为什么是new Object[0]呢?)
        //用Object[0]来代替null 很多时候我们需要传递参数的类型,而不是传null,所以用Object[0]
        private static final Object[] EMPTY_ELEMENTDATA = new Object[0];  
        // 一个空对象,如果使用默认构造函数创建,则默认对象内容默认是该值  
        private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = new Object[0];  
        // 当前数据对象存放地方,当前对象不参与序列化(主要是关键字transient起作用的)  
        transient Object[] elementData;  
        // 当前数组长度  
        private int size;  
        // 数组最大长度  
        private static final int MAX_ARRAY_SIZE = 2147483639;  
    }  
    

    방법.
    구조 방법
    추가 방법
    add 방법 은 Array List 의 중요 한 방법 이 라 고 할 수 있 습 니 다. 먼저 총람 하 겠 습 니 다.
    // 直接添加元素
    public boolean add(E e) {        
        ensureCapacityInternal(size + 1);         
        elementData[size++] = e;        
        return true;    
    }
    // 插入到特定的位置上
    public void add(int index, E element) {        
        rangeCheckForAdd(index);        
        ensureCapacityInternal(size + 1);        
        System.arraycopy(elementData, index,elementData, index + 1,size - index);    
        elementData[index] = element;        
        size++;   
    }
    

    add(E,e)
    단계:
  • 용량 확장 필요 여부 검사
  • 요소 삽입
  • 우선, 우 리 는 이 방법 을 본다.
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);       
        elementData[size++] = e;        
        return true;    
    }
    
  • list 용량 을 먼저 확인 하고 용량 을 추가 하여 필요 한 지 확인 하 세 요
  • 원소 첨가
  • 다음은 이 소 용량 (+ 1) 이 우리 의 요 구 를 만족 시 킬 수 있 는 지 살 펴 보 겠 습 니 다.
    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        // 想要得到最小的容量(不浪费资源)
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }
    
    private void ensureCapacityInternal(int minCapacity) { 
        // 明确容量大小
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }
    
    private void ensureExplicitCapacity(int minCapacity) {        
        modCount++;      
        // 如果要的最小容量比数组的长度要打,那么就调用grow()来进行扩容。
        if (minCapacity - elementData.length > 0)          
            grow(minCapacity);   
    }
    

    그리고 grow 확장 방법 을 사용 합 니 다.
    요약:
  • 우선 배열 의 용량 이 충분 한 지 확인 해 보 자.
  • 원래 의 1.5 배
  • 로 확대
  • 첫 번 째 용량 을 확대 한 후에 도 용량 이 minCapacty 보다 작 으 면 용량 을 minCapacity 로 확대 한다.
  • 충분: 직접 추가
  • 부족: 확장

  • add(int index,E element)
    단계:
  • 각 표 검사
  • 공간 점검, 필요 하면 용량 확대
  • 요소 삽입
  • public void add(int index, E element) { 
        // 检查角标是否越界
        rangeCheckForAdd(index);  
        // 扩容
        ensureCapacityInternal(size + 1);  
        // 调用arraycopy()来进行插入C++编写的
        System.arraycopy(elementData, index, elementData, index + 1,size - index);       
        elementData[index] = element;        
        size++;    
    }
    

    성장 확장
    grow () 방법
    private void grow(int minCapacity) {               
        int oldCapacity = elementData.length;   
        // 相当于扩容1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);        
        if (newCapacity - minCapacity < 0)            
            newCapacity = minCapacity;        
        if (newCapacity - MAX_ARRAY_SIZE > 0)            
            newCapacity = hugeCapacity(minCapacity);  
        // 扩容完以后,调用的是copyOf()方法
        elementData = Arrays.copyOf(elementData, newCapacity);    
    }
    

    copy Of () 방법
    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {       
        @SuppressWarnings("unchecked")        
        T[] copy = ((Object)newType == (Object)Object[].class)           
            ? (T[]) new Object[newLength]            
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);        
        System.arraycopy(original, 0, copy, 0,                         
                         Math.min(original.length, newLength));        
        return copy;    
    }
    

    get 방법
    순서
  • 각 표 검사
  • 원 소 를 되 돌려 줍 니 다
  •  public E get(int index) {  
         // 检查角标
         rangeCheck(index); 
         // 返回具体元素
         return elementData(index);    
     }
    
    // 检查角标
    private void rangeCheck(int index) {        
        if (index >= size)            
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));  
    }
    
    // 返回元素 
    E elementData(int index) {            
        return (E) elementData[index];    
    }
    

    set 방법
    단계:
  • 각 표 검사
  • 대체 원소
  • 옛 값 되 돌리 기
  • public E set(int index, E element) {   
        // 检查角标
        rangeCheck(index);   
        // 将值进行替换,返回旧值
        E oldValue = elementData(index);        
        elementData[index] = element;        
        return oldValue;    
    }
    

    remove 방법
    순서
  • 각 표 검사
  • 원소 삭제
  • 이동 해 야 할 개 수 를 계산 하고 이동
  • null 로 설정 하여 GC 를 회수
  • 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; 
        return oldValue;    
    }
    

    좋은 웹페이지 즐겨찾기