본문 바로가기
Java

자바 중급 2편 - ArrayList(2)

by KongJiHoon 2025. 7. 19.

✅ 동적 배열

  • 배열은 고정 크기이기 때문에 한계(capacity)를 넘으면 더 이상 데이터를 추가할 수 없음.
    즉, elementData.length == size일 경우 add()에서 예외가 발생함.
  • 방법
    • 배열이 가득 찼을 때, 기존 배열의 크기를 2배로 늘린 새로운 배열을 만들고 데이터를 복사
    • 이를 통해 유동적인 크기 조절이 가능해짐
package com.example.collection.array;

import java.util.Arrays;

public class MyArrayListV2 {


    private static final int DEFAULT_CAPACITY = 5;

    private Object[] elementData;

    private int size = 0;

    public MyArrayListV2() {
        elementData = new Object[DEFAULT_CAPACITY];
    }

    public MyArrayListV2(int initialCapacity) {
        elementData = new Object[initialCapacity];
    }

    public int size() {
        return size;
    }

    public void add(Object e) {

        // 코드 추가
        if (size == elementData.length) {

            grow();

        }

        elementData[size++] = e;

    }

    // 코드 추가
    private void grow() {
        int oldCapacity = elementData.length;
        int newCapacity =oldCapacity * 2;

        // 배열을 새로만들고, 기존 배열을 새로운 배열에 복사


        elementData = Arrays.copyOf(elementData, newCapacity);
    }


    public Object get(int index) {
        return elementData[index];
    }

    public Object set(int index, Object e) {

        Object oldValue = get(index);

        elementData[index] = e;

        return oldValue;
    }

    public int indexOf(Object o) {

        for (int i = 0; i < size; i++) {
            if (o.equals(elementData[i])) {
                return i;
            }
        }

        return -1;
    }

    public String toString() {

        return Arrays.toString(Arrays.copyOf(elementData, size)) + " size = " + size + ", capacity = " + elementData.length;

    }


}

 

 

private void grow() {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity * 2;
    elementData = Arrays.copyOf(elementData, newCapacity);
}

📌 Arrays.copyOf()는 내부적으로 System.arraycopy()를 사용하여 성능이 빠름.

실행 결과

[] size=0, capacity=2
[a] size=1, capacity=2
[a, b] size=2, capacity=2
[a, b, c] size=3, capacity=4  ← grow()
[a, b, c, d] size=4, capacity=4
[a, b, c, d, e] size=5, capacity=8  ← grow()

 

 

✅ 기능 추가 - addFirst(), addLast(), remove()

 

add(int index, Object e)

// 코드 추가
public void add(int index, Object e) {
    if (size == elementData.length) {

        grow();

    }

    // 데이터 이동

    shiftRightFrom(index);

    elementData[index] = e;
    size++;
}

// 코드 추가, 요소의 마지막부터 index까지 오른쪽으로 밀기
private void shiftRightFrom(int index) {

    for (int i = size; i > index ; i--) {
        elementData[i] = elementData[i - 1];
    }


}
  • 지정한 인덱스에 값을 삽입하고, 기존 요소들을 오른쪽으로 한 칸씩 밀기
  • 삽입 위치가 앞쪽일수록 많은 요소 이동이 발생 → O(n)



remove(int index) 

// 코드 추가
public Object remove(int index) {

    Object oldValue = get(index);

    // 데이터 이동
    shiftLeftFrom(index);

    size--;

    elementData[size] = null;
    return oldValue;

}

// 코드 추가 요소의 index부터 마지막까지 왼쪽으로 밀기
private void shiftLeftFrom(int index) {


    for (int i = index; i < size - 1; i++) {

        elementData[i] = elementData[i + 1];

    }


}
  • 삭제된 위치 뒤의 요소들을 왼쪽으로 한 칸씩 당김
  • 삭제도 앞에서 일어날수록 이동량이 커짐 → O(n)
package com.example.collection.array;

public class MyArrayListV3Main {

    public static void main(String[] args) {


        MyArrayListV3 list = new MyArrayListV3();

        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        System.out.println(list);

        // 원하는 위치에 추가
        System.out.println("addLast");
        list.add(list.size(), "addLast"); //O(1)
        System.out.println(list);

        System.out.println("addFirst"); // O(n)
        list.add(0, "addFirst");
        System.out.println(list);

        Object remove = list.remove(list.size() - 1); // O(1)
        System.out.println("remove = " + remove);
        System.out.println(list);

        Object remove1 = list.remove(2);// O(n)
        System.out.println("remove1 = " + remove1);
        System.out.println(list);

    }
}

 

 

📌 정리

항목 설명
add(e) 평균 O(1) (가득 찼을 때만 O(n) grow)
add(index, e) 최악 O(n) (중간 삽입 시 shift 필요)
remove(index) 최악 O(n) (중간 삭제 시 shift 필요)
자동 확장 grow()로 구현 (2배씩 증가)
메모리 누수 방지 삭제 후 null 처리

'Java' 카테고리의 다른 글

자바 중급 2편 - LinkedList  (2) 2025.08.03
자바 중급 2편 - ArrayList(3)  (0) 2025.07.20
자바 중급 2편 - ArrayList(1)  (0) 2025.07.07
자바 중급 2편 - 제네릭(4)  (0) 2025.06.01
자바 중급 2편 - 제네릭(3)  (0) 2025.05.31