-
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