ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java 버전 별 ArrayList add 동작
    JAVA 2023. 9. 6. 18:51

    Java 6

    public boolean add(E e) {
    	ensureCapacity(size + 1);  // Increments modCount!!
    	elementData[size++] = e;
        return true;
    }

    Java 6 에서 ArrayList add이다. ensureCapacity에 현재 size +1을 전달하여 크기를 확인한다.

    public void ensureCapacity(int minCapacity) {
    	modCount++;
    	int oldCapacity = elementData.length;
    	if (minCapacity > oldCapacity) {
    	    Object oldData[] = elementData;
    	    int newCapacity = (oldCapacity * 3)/2 + 1;
        	    if (newCapacity < minCapacity)
    		newCapacity = minCapacity;
                // minCapacity is usually close to size, so this is a win:
                elementData = Arrays.copyOf(elementData, newCapacity);
    	}
    }

    ensureCapacity에서 기존 list의 크기와 비교해서 크기가 늘어야 한다면 기존 크기에 *3 / 2 +1하여 새로운 사이즈를 만들고 크기를 정하여 배열을 복사해준다.

     

    Java 7

        public boolean add(E e) {
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            elementData[size++] = e;
            return true;
        }

    Java7에서의 add이다. ensureCapacityInternal로 크기를 확인해준다.

        private void ensureCapacityInternal(int minCapacity) {
            if (elementData == EMPTY_ELEMENTDATA) {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
    
            ensureExplicitCapacity(minCapacity);
        }

    데이터가 초기 빈 값이라면 DEFAULT_CAPACITY인 10과 비교하여 큰 값을 capacity로 설정하여 ensuerExplicitCapacity에 넘겨준다.

        private void ensureExplicitCapacity(int minCapacity) {
            modCount++;
    
            // overflow-conscious code
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }

    이렇게 넘어온 minCapacity가 현재 list 길이보다 크면 grow 를 실행한다.

        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);
        }

    Java7에서는 Java 6과 다르게 비트 연산으로 새로운 capacity를 계산한다. 만약 계산된 capacity가 MAX_ARRAY_SIZE (Java 7에서는 Integer.MAX_VALUE - 8) 보다 크다면 hugeCapacity를 호출한다.

        private static int hugeCapacity(int minCapacity) {
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError();
            return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
        }

    만약 이렇게 넘어온 capacity가 overflow 되어서 음수가 되었다면 에러를 발생시킨다. 그게 아니라면 최대 Integer.MAX_VALUE 크기를 반환한다.

     

    Java 8

        public boolean add(E e) {
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            elementData[size++] = e;
            return true;
        }

    Java 8에서의 add이다. Java 7 과 마찬가지로 ensuerCapacityInternal을 호출해준다.

        private void ensureCapacityInternal(int minCapacity) {
            ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
        }
        private static int calculateCapacity(Object[] elementData, int minCapacity) {
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                return Math.max(DEFAULT_CAPACITY, minCapacity);
            }
            return minCapacity;
        }

    ensuerCapacityInternal 이다. Java 7 과 달라진점은 Java 7 에서는 encusrCapacityInternal 에서 계산하던 작업을 별도로 calculateCapacity로 분리해서 작업한다. 또 기존 Java 7 에서의 EMPTY_ELEMANTDATA 가 아니라 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 로 바뀌었다. 이건 초기값 없이 ArrayList를 초기화하면 기본적으로 갖게되는 값이다. 이 경우 기본적인 초기 사이즈는 10을 갖게 된다.
    Java 8에서는 Java 7과는 다르게 빈 elementData와 초기 elementData를 분리해서 관리하고있다.

    'JAVA' 카테고리의 다른 글

    Java Generic Compile 동작  (0) 2023.09.11
    JVM Memory Area  (0) 2023.09.08
    Java Thread Safety 한 개발  (0) 2023.08.29
    Singleton 구현 기법  (0) 2023.08.27
    Transaction 격리 레벨 / 전파 모델  (0) 2023.08.06
Designed by Tistory.