ArrayList의 add()로 보는 동적 복사 과정

2024. 12. 25. 02:28·👶🏻 CS/Data Structure

add()

public boolean add(E e) {  
    modCount++;  
    add(e, elementData, size);  
    return true;  
}

private void add(E e, Object[] elementData, int s) {  
    if (s == elementData.length)  
        elementData = grow();  
    elementData[s] = e;  
    size = s + 1;  
}

 

처음 add(E e)메서드를 호출하게 되면 오버로딩된 add(e, elementData, size)를 호출한다.
이 메서드에는 추가할 데이터(e), 현재 배열(elementData), 배열의 현재 크기(size)가 전달된다.

 

현재 배열 크기(elementData.length)와 데이터 추가 후 배열 크기(s)를 비교한다.
만약 배열이 가득 찬 경우 배열 크기를 확장하기 위해 grow() 메서드를 호출한다.

 

grow()

private Object[] grow() {  
    return grow(size + 1);  
}

private Object[] grow(int minCapacity) {  
    int oldCapacity = elementData.length;  // 현재 배열의 크기
    if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {  
        int newCapacity = ArraysSupport.newLength(oldCapacity,  
                minCapacity - oldCapacity, oldCapacity >> 1);  
        return elementData = Arrays.copyOf(elementData, newCapacity);  
    } else {  
        return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];  
    }  
}

현재 배열의 크기를 가져와 변수 oldCapacity에 저장한다. 예를 들어, 현재 배열의 크기가 10이라면 oldCapacity = 10이 된다.

그다음 ArraysSupport.newLength 메서드를 호출하여 oldCapacity의 절반을 더해 새로운 배열 크기(newCapacity) 15를 계산한다.

이후 Arrays.copyOf를 사용해 크기가 15인 배열을 생성하고 기존 데이터를 복사한다.

 

기존 배열은? 🤔

기존 배열(크기가 10이던)은 더 이상 참조되지 않아 GC에 의해 제거된다.

 

Arrays.copyOf()은 얕은 복사? 깊은 복사?

많은 블로그에서 깊은 복사의 방법으로 Arrays.copyOf()을 설명하지만, 이는 틀린 설명이다.

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

코드를 보면 System.arraycopy()라는 메서드를 수행하는데 이 메서드는 original[i]의 값을 copy[i]에 복사한다.

즉, 기본 타입 배열인 경우 배열의 각 요소 값을 복사하고, 참조 타입 배열인 경우 배열 요소가 참조하는 객체의 주소값(참조)을 복사한다.

 

기본 타입 배열은 값 자체를 복사하므로 원본과 독립적이라는 점에서 깊은 복사라고 생각할 수 있지만 기본 타입의 경우 객체 참조가 아니라 값 자체를 다루기 때문에, 얕은 복사가 동작하더라도 결과적으로 원본에 영향을 미치지 않아 깊은 복사처럼 보이는 것이다.

저작자표시 비영리 (새창열림)

'👶🏻 CS > Data Structure' 카테고리의 다른 글

HashMap(구현 방식, 해싱, 해시 함수, 해시 충돌)  (0) 2024.12.23
'👶🏻 CS/Data Structure' 카테고리의 다른 글
  • HashMap(구현 방식, 해싱, 해시 함수, 해시 충돌)
현주먹
현주먹
대구 불주먹 출신 현주먹의 개발.log
  • 현주먹
    현주먹의 개발로그
    현주먹
  • 전체
    오늘
    어제
    • 전체글 (179)
      • 👶🏻 CS (15)
        • Operating System (7)
        • DB (5)
        • Data Structure (2)
        • Software Engineering (1)
      • 💻 Dev (54)
        • Java & OOP (24)
        • Spring (4)
        • DB&JPA (6)
        • Test Code (1)
        • JSP & Servlet (13)
        • Etc (6)
      • 💡 Algorithm (25)
        • 인프런 (9)
        • 백준 (16)
      • 🛠 DevOps & Tool (11)
        • Linux (4)
        • AWS (1)
        • Git (2)
        • Etc (4)
      • 📝 끄적끄적 (74)
        • 후기 및 회고 (11)
        • TDD, 클린 코드 with Java 17기 (3)
        • F-Lab (23)
        • 🖥️ 자바의 정석 (11)
        • 📖 Clean Code (3)
        • 항해99 코테 스터디 (11)
        • 📖 가상 면접 사례로 배우는 대규모 시스템 설계 .. (11)
  • 블로그 메뉴

    • 🐈‍⬛ GitHub
    • TIL repository
  • 인기 글

  • 최근 글

  • 최근 댓글

  • 태그

    99클럽
    F-Lab
    티스토리챌린지
    til
    개발자멘토링
    오라클
    jsp
    2025스프링캠프
    JPA
    f-lab 후기
    자바의신절판
    에프랩 후기
    jsp 2.3 웹 프로그래밍: 기초부터 중급까지
    데브클럽
    인프런 특정문자뒤집기
    자바의정석
    코딩테스트준비
    오블완
    개구리책
    NextSTEP
    TDD 클린 코드 with Java
    백준
    객체지향
    ==와 equals()
    개발자취업
    로또 미션
    에프랩
    코테스터디
    항해99
    C
  • hELLO· Designed By정상우.v4.10.2
현주먹
ArrayList의 add()로 보는 동적 복사 과정
상단으로

티스토리툴바