배열(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 |