티스토리 뷰

 

개발을 하다 보면 데이터를 담을 바구니가 필요합니다. 이때 가장 먼저 마주하는 선택지가 바로 **배열(Array)**과 **리스트(ArrayList)**죠. 단순히 "크기가 변하느냐 아니냐"의 차이를 넘어, 이 선택이 시스템의 메모리 효율과 응답 속도에 어떤 나비효과를 불러오는지 깊이 있게 파헤쳐 보겠습니다.


1. 정적(Static)인가, 동적(Dynamic)인가?

자바에서 배열은 정적 할당의 대명사입니다. 메모리 상에 연속된 공간을 점유하며, 한 번 선언된 크기는 죽을 때까지 바꿀 수 없습니다. 반면, ArrayList는 내부적으로 배열을 품고 있으면서도 상황에 따라 크기를 늘리는 동적 할당 방식을 취합니다.

💡 비유로 이해하기

  • 배열: 미리 칸막이가 쳐진 기차 좌석입니다. 10호차까지 예약했다면, 손님이 11명이 와도 칸을 늘릴 수 없습니다.
  • ArrayList: 손님이 올 때마다 칸을 이어 붙이는 마법 열차입니다. 하지만 칸을 붙일 때 열차 전체를 멈추고 새 선로로 옮겨야 하는 비용이 발생하죠.

2. Deep Dive: 메모리 레이아웃과 성능의 비밀

데이터 타입의 제약

배열은 **Primitive type(int, double 등)**과 **Reference type(Object)**을 모두 담을 수 있습니다. 하지만 ArrayList는 오직 **객체(Object)**만 허용합니다. 우리가 ArrayList<Integer>를 사용할 때 내부적으로는 기본형 int가 Integer 객체로 변환되는 Auto-boxing 과정이 일어나며, 이 과정에서 추가적인 메모리 오버헤드가 발생합니다.

데이터 추가의 원리

ArrayList가 가득 차면 어떻게 될까요? 보통 기존 용량의 약 1.5배 큰 새로운 배열을 만들고 기존 데이터를 복사($O(n)$)합니다.


3. 실전 예제: 이커머스 장바구니 로직

단순한 예제 대신, 사용자가 상품을 담을 때마다 실시간으로 할인이 적용되는 장바구니 로직을 통해 두 자료구조의 차이를 확인해 봅시다.

고정된 메뉴판 (Array 활용)

변경되지 않는 카테고리나 고정 메뉴는 배열이 가장 빠르고 가볍습니다.

Java
 
// 카테고리는 서비스 운영 중 변할 일이 거의 없으므로 고정 배열 사용
String[] categories = {"ELECTRONICS", "FASHION", "FOOD"};

public void printCategory(int index) {
    // 인덱스 접근 속도: O(1)
    System.out.println("Selected: " + categories[index]);
}

유동적인 장바구니 (ArrayList 활용)

사용자가 무엇을 담을지 모르는 상황에서는 ArrayList가 필수적입니다.

Java
 
import java.util.ArrayList;
import java.util.List;

public class ShoppingCart {
    // 상품 객체를 담는 리스트 (동적 추가/삭제 대응)
    private List<Product> items = new ArrayList<>();

    public void addItem(Product product) {
        // 내부적으로 용량(Capacity)을 체크하고 필요시 확장함
        items.add(product);
    }

    public double calculateTotal() {
        return items.stream()
                    .mapToDouble(Product::getPrice)
                    .sum();
    }
}

🛠 트러블슈팅: java.lang.ArrayIndexOutOfBoundsException

배열을 다룰 때 가장 흔한 실수입니다. ArrayList는 size()를 통해 유효 범위를 체크하기 쉽지만, 배열은 length와 인덱스 $n-1$의 관계를 항상 명심해야 합니다. 특히 반복문에서 i <= array.length라고 작성하는 실수를 주의하세요.


4. Trade-offs: 무엇을 선택할 것인가?

비교 항목 배열 (Array) 리스트 (ArrayList)
속도 최적화된 메모리 접근으로 매우 빠름 객체 포인터 참조로 인해 상대적으로 느림
유연성 크기 변경 불가능 동적 크기 조절 가능
메모리 필요한 만큼만 할당 (효율적) 여유 공간을 미리 확보하므로 낭비 발생 가능
타입 기본형/객체 모두 가능 객체만 가능 (제네릭 활용)

5. 결론 및 통찰

데이터의 개수가 확정되어 있고 성능이 극도로 중요하다면 배열을, 데이터의 변화가 잦고 생산성이 중요하다면 ArrayList를 선택하는 것이 정석입니다.

현대적인 자바 개발에서는 가독성과 Collection API의 강력한 기능(Stream, 정렬 등) 때문에 ArrayList를 기본으로 사용하곤 합니다. 하지만 대규모 트래픽을 처리하거나 메모리 효율이 중요한 알고리즘을 설계할 때는 배열이 주는 원시적인 속도가 강력한 무기가 됩니다.

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함