본문 바로가기
Java

[Java] 리스트(List) 와 배열(Array)의 차이점

by goblin- 2024. 9. 29.

배열(Array)과 리스트(List)의 차이점에 대해 이론적인 부분을 중점으로 설명하고, 간단한 코드 예시를 통해 차이점을 이해할 수 있도록 하겠습니다.

 

1. 배열(Array)

 

1.1 기본 개념

 

배열고정된 크기를 가진 동일한 타입의 데이터를 저장하는 자료구조입니다. 한 번 생성된 배열의 크기는 변경할 수 없습니다.

배열은 인덱스를 통해 **O(1)**의 시간 복잡도로 빠르게 요소에 접근할 수 있습니다.

배열은 메모리에서 연속된 공간을 차지하며, 각 요소는 연속적으로 저장됩니다. 이는 메모리 사용 효율이 높고, 액세스 속도가 빠르다는 장점이 있습니다.

 

1.2 배열의 특징

 

고정 크기: 배열은 선언 시 크기가 고정되며, 중간에 크기를 변경할 수 없습니다.

동일한 타입: 배열은 동일한 타입의 데이터를 저장해야 합니다. 예를 들어, 정수 배열에는 정수만 저장할 수 있습니다.

빠른 접근: 인덱스를 통해 빠르게 데이터에 접근할 수 있습니다.

메모리 사용 효율적: 배열은 연속된 메모리를 사용하므로, 메모리 사용이 효율적입니다.

 

1.3 간단한 코드 예시: 배열

public class ArrayExample {
    public static void main(String[] args) {
        // 배열 선언과 초기화
        int[] numbers = {1, 2, 3, 4, 5};
        
        // 배열의 크기 출력
        System.out.println("배열의 크기: " + numbers.length);  // 출력: 5
        
        // 배열 요소 접근 (인덱스)
        System.out.println("첫 번째 요소: " + numbers[0]);  // 출력: 1
        
        // 배열 요소 수정
        numbers[2] = 10;
        System.out.println("수정된 세 번째 요소: " + numbers[2]);  // 출력: 10
    }
}

2. 리스트(List)

 

2.1 기본 개념

 

**리스트(List)**는 동적으로 크기가 변할 수 있는 자료구조입니다. 자바에서는 List 인터페이스를 통해 리스트를 사용하며, 가장 많이 사용하는 구현체는 **ArrayList**와 **LinkedList**입니다.

리스트는 크기가 동적으로 변화할 수 있어, 데이터의 삽입 및 삭제가 자유롭습니다.

**ArrayList**는 내부적으로 배열을 사용하지만, 크기가 가득 차면 자동으로 배열을 확장하여 새로운 데이터를 추가할 수 있습니다.

 

2.2 리스트의 특징

 

동적 크기: 리스트는 크기가 자동으로 조정됩니다. 즉, 데이터가 추가되면 리스트의 크기가 증가하고, 삭제되면 크기가 줄어듭니다.

여러 타입: 리스트는 객체 타입의 데이터를 저장할 수 있어, 다양한 타입의 데이터를 저장할 수 있습니다.

메모리 사용 비효율적: 리스트는 배열보다 메모리 관리가 덜 효율적일 수 있지만, 동적 크기유연성 덕분에 삽입/삭제 작업이 자주 일어나는 경우 유리합니다.

 

2.3 간단한 코드 예시: 리스트

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

public class ListExample {
    public static void main(String[] args) {
        // ArrayList 생성
        List<Integer> numbers = new ArrayList<>();
        
        // 요소 추가
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);
        numbers.add(4);
        
        // 리스트 크기 출력
        System.out.println("리스트의 크기: " + numbers.size());  // 출력: 4
        
        // 요소 접근
        System.out.println("첫 번째 요소: " + numbers.get(0));  // 출력: 1
        
        // 요소 수정
        numbers.set(2, 10);
        System.out.println("수정된 세 번째 요소: " + numbers.get(2));  // 출력: 10
    }
}

 

3. 배열(Array)과 리스트(List)의 차이점

 

3.1 크기

 

배열: 배열의 크기는 고정되어 있습니다. 배열을 선언할 때 크기를 지정해야 하며, 한 번 설정된 크기는 변경할 수 없습니다.

리스트: 리스트는 동적으로 크기가 변화할 수 있습니다. 데이터를 추가하면 자동으로 리스트의 크기가 확장되며, 데이터를 삭제하면 리스트의 크기가 줄어듭니다.

 

배열의 크기 문제 예시

// 배열은 크기를 미리 지정해야 함
int[] numbers = new int[5];

// 배열의 크기를 초과하는 요소 추가는 불가능
numbers[5] = 10;  // 오류 발생: ArrayIndexOutOfBoundsException

 

리스트의 크기 동적 조정 예시

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

// 리스트는 크기를 동적으로 조정할 수 있음
List<Integer> numbers = new ArrayList<>();
numbers.add(1);  // 리스트 크기 자동 증가
numbers.add(2);
numbers.add(3);  // 계속해서 추가 가능

 

3.2 데이터 접근 속도

 

배열: 배열은 인덱스를 통해 직접 접근할 수 있기 때문에, **O(1)**의 시간 복잡도로 빠르게 요소에 접근할 수 있습니다.

리스트: ArrayList는 배열처럼 인덱스를 통해 빠르게 접근할 수 있지만, LinkedList는 인덱스를 통한 랜덤 접근이 느립니다. LinkedList는 요소를 찾기 위해 노드를 순차적으로 탐색해야 하기 때문에, **O(n)**의 시간 복잡도를 가집니다.

 

배열과 리스트의 데이터 접근 예시

// 배열에서 인덱스 2의 요소에 접근
int[] numbers = {1, 2, 3, 4, 5};
System.out.println(numbers[2]);  // 출력: 3

// ArrayList에서 인덱스 2의 요소에 접근
List<Integer> numberList = new ArrayList<>(numbers.length);
numberList.add(1);
numberList.add(2);
numberList.add(3);
System.out.println(numberList.get(2));  // 출력: 3

 

3.3 삽입 및 삭제 성능

 

배열: 배열은 크기가 고정되어 있기 때문에 중간에 데이터를 삽입하거나 삭제하는 것이 비효율적입니다. 데이터를 삽입하거나 삭제하려면 나머지 요소를 이동시켜야 하며, 이는 시간과 메모리 비용이 많이 듭니다.

리스트: 리스트는 데이터 삽입과 삭제가 자유롭습니다. 특히 LinkedList는 중간에 데이터를 삽입하거나 삭제할 때 **O(1)**의 시간 복잡도로 효율적입니다. 하지만, ArrayList는 내부적으로 배열을 사용하기 때문에 중간 삽입/삭제 시 느릴 수 있습니다.

 

배열에서 데이터 삽입의 문제 예시

int[] numbers = {1, 2, 3, 4, 5};

// 배열의 중간에 요소를 추가하려면 새로운 배열을 만들어야 함
int[] newNumbers = new int[6];
System.arraycopy(numbers, 0, newNumbers, 0, 2);
newNumbers[2] = 6;  // 새로운 요소 추가
System.arraycopy(numbers, 2, newNumbers, 3, numbers.length - 2);

for (int number : newNumbers) {
    System.out.println(number);  // 출력: 1, 2, 6, 3, 4, 5
}

 

리스트에서 데이터 삽입의 간편함 예시

List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);

// 중간에 요소 추가
numbers.add(2, 10);  // 인덱스 2에 10을 삽입

for (int number : numbers) {
    System.out.println(number);  // 출력: 1, 2, 10, 3
}

 

4. 정리

 

배열(Array)

 

고정 크기로 생성되며, 데이터 추가나 삭제 시 크기를 변경할 수 없음.

인덱스를 통한 빠른 접근이 가능하지만, 데이터 삽입과 삭제 시 비효율적.

메모리 사용이 효율적이며, 성능이 중요한 상황에서 적합.

 

리스트(List)

 

동적 크기로 자동으로 크기를 조정할 수 있으며, 데이터 삽입과 삭제가 유연.

ArrayList는 인덱스 접근이 빠르고, LinkedList는 삽입/삭제 작업이 빠름.

메모리 사용은 배열보다 덜 효율적일 수 있지만, 유연성동적 크기가 필요할 때 적합.

 

배열은 고정된 크기와 성능이 중요한 경우 사용되고, 리스트는 데이터가 자주 변하거나 크기가 동적으로 변해야 하는 상황에 적합합니다.

'Java' 카테고리의 다른 글

[Java] Stream  (2) 2024.09.29
[Java] Optional  (2) 2024.09.29
[Java] 람다 표현식(Lamda Expression)  (0) 2024.09.29
[Java] Enum  (1) 2024.09.28
[Java] 상속 vs 합성  (0) 2024.09.28