자바의 List는 가장 자주 쓰이는 컬렉션 타입 중 하나로, 순서가 있는 데이터 집합을 다룰 때 사용된다.
간단히 말하면 배열처럼 순서대로 데이터를 저장하고 관리할 수 있는 자료구조이다.
아래에 주요 내용을 정리해 보았다.
List란?
- List는 java.util 패키지에 속한 인터페이스. (List<Integer> list = new List<>(); 같이 초기화를 못한다.)
- 중복된 요소를 허용하고, 순서대로 요소를 유지한다.
- 인덱스를 사용해서 요소에 접근할 수 있어요 (list.get(0) 같은 식으로).
1. 주요 구현 클래스
클래스 이름 | 특징 요약 |
ArrayList | 배열 기반, 빠른 검색, 느린 삽입/삭제 |
LinkedList | 노드 기반, 삽입/삭제 빠름, 검색 느림 |
Vector | 예전 스타일, 동기화 됨 (멀티스레드용) |
Stack | LIFO 구조, Vector를 상속함 (Stack의 문제때문에 Deque(덱) 사용을 권장함) |
2. 자주 쓰는 메서드 간단 예시
List<String> list = new ArrayList<>();
list.add("Apple"); // 요소 추가
list.add("Banana");
list.add(1, "Orange"); // 인덱스에 삽입
String fruit = list.get(0); // 요소 읽기
list.set(0, "Peach"); // 요소 수정
list.remove("Banana"); // 값으로 삭제
list.remove(0); // 인덱스로 삭제
int size = list.size(); // 크기 확인
boolean hasOrange = list.contains("Orange"); // 포함 여부 확인
list.clear(); // 전체 삭제
3. for-each 루프 예시
for (String item : list) {
System.out.println(item);
}
4. 제네릭(Generic)을 이용한 타입 안전성
List<String>, List<Integer> 처럼 사용해서 타입 안정성을 확보할 수 있다.
덕분에 형 변환 없이 사용할 수 있다.
각 구현체의 차이점은 무엇일까?
ArrayList, LinkedList, Vector는 모두 List 인터페이스를 구현한 클래스들이고, 비슷해 보이지만
동작 방식이나 성능, 사용 목적이 조금씩 다르다.
아래에 각각의 차이점을 정리해 보았다.
1. 차이점 요약
특성 | ArrayList | LinkedList | Vector |
내부 구조 | 배열 기반 | 이중 연결 리스트 기반 | 배열 기반 |
검색 속도 | 빠름 (index 접근 O(1)) | 느림 (순차 탐색 O(n)) | 빠름 (index 접근 O(1)) |
삽입/삭제 | 느림 (중간에선 O(n)) | 빠름 (중간 삽입/삭제 O(1)) | 느림 (동기화로 인해) |
동기화 | ❌ 비동기 | ❌ 비동기 | ✅ 동기화 (멀티스레드에 안전) |
사용 시기 | 읽기 중심 | 삽입/삭제 중심 | 멀티스레드 환경에서 필요할 때 |
2. 언제 어떻게 써야 할까?
차이점은 알았지만 결국 언제 어떤 걸 써야 할지 모르면 힘들다.
각 List 구현체 (ArrayList, LinkedList, Vector)는 내부 구조와 동작 방식이 다르기 때문에,
상황에 따라 잘 골라 써야 성능이나 안정성 면에서 이득을 볼 수 있다.
다음과 같은 상황에 쓰면 편할것이다.
상황 추천 | 클래스 |
읽기/검색이 많고 동기화 필요 없음 | ArrayList |
삽입/삭제가 빈번함 (특히 중간 위치) | LinkedList |
멀티스레드 환경에서 사용 필요 | Vector (하지만 Collections.synchronizedList() 또는 CopyOnWriteArrayList 추천됨) |
2-1. ArrayList – 읽기/탐색 위주 데이터에 적합
특징
- 내부 구조: 배열 기반
- 장점: 인덱스로 빠르게 접근 가능 (get() 속도 빠름)
- 단점: 중간 삽입/삭제 시 느림 (뒤 요소 전부 밀어야 함)
사용 예시
상황 | 이유 |
게시판 글 목록 | 인덱스로 바로 접근해서 출력 |
상품 리스트 | 빠른 탐색/정렬이 중요 |
유저 순위표 | 변경이 적고 조회가 잦음 |
페이징 처리 | 인덱스 기반 분할 처리 용이 |
2- 2. LinkedList – 삽입/삭제가 잦거나 큐/스택처럼 동작할 때 적합
특징
- 내부 구조: 이중 연결 리스트
- 장점: 앞뒤 삽입/삭제 빠름 (addFirst, removeLast 등)
- 단점: 인덱스로 접근 시 느림 (한 칸씩 따라가야 함)
사용 예시
상황 | 이유 |
명령어 실행 히스토리 (Undo/Redo) | 끝에서 삽입/삭제가 빠름 |
게임 처리 순서 (작업 큐) | FIFO 구조 |
실시간 알림 대기열 | 빠른 순차 처리 필요 |
음악 재생 대기열 | 재생 순서 수정/제거가 잦음 |
2-3. Vector – 멀티스레드 환경에서 쓰기 안정성을 보장할 때 사용
특징
- 내부 구조: 배열 기반 (ArrayList와 유사)
- 장점: 동기화 되어 있어 멀티스레드에서 안전
- 단점: 단일 스레드 환경에서는 느림 (성능 손해)
사용 예시
이유 상황 | 이유 |
채팅 메시지 저장 | 여러 유저의 입력을 동시에 받음 |
실시간 로그 기록 | 다중 스레드에서 기록 발생 가능 |
동기화된 리스트 필요 | 데이터를 안전하게 공유해야 함 |
참고: 최신 자바에서는 Vector보다
Collections.synchronizedList(new ArrayList<>())
또는 CopyOnWriteArrayList를 더 많이 사용한다고 함.
2-4 정리: 상황별 추천 표
상황추천 | 구현체 | 이유 |
조회/정렬이 많은 경우 | ArrayList | 빠른 인덱스 접근 |
삽입/삭제가 잦은 경우 | LinkedList | 앞뒤 수정이 빠름 |
멀티스레드 환경 | Vector (또는 동기화된 리스트) | 동기화 제공 |
FIFO 큐 처리 | LinkedList | Queue 인터페이스 구현 |
스택처럼 사용 | LinkedList | Deque 기능도 있음 |
3. 자주 쓰는 메서드 정리
ArrayList, LinkedList, Vector 세개의 구현체에서 공통으로 사용할 수 있는 메서드를 정리해 보았다.
add(E e); // 요소 추가
add(int index, E e); // 특정 위치에 삽입
get(int index); // 인덱스로 요소 가져오기
set(int index, E e); // 인덱스의 요소 수정
remove(int index); // 인덱스의 요소 제거
remove(Object o); // 값으로 요소 제거
contains(Object o); // 포함 여부 확인
clear(); // 전체 삭제
size(); // 리스트 크기 확인
isEmpty(); // 비어있는지 확인
4. 간단한 구현 예제
1. ArrayList 구현
import java.util.ArrayList;
public class ArrayListExample {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
list.add("C++");
for (String lang : list) {
System.out.println(lang);
}
}
}
2. LinkedList 구현
import java.util.LinkedList;
public class LinkedListExample {
public static void main(String[] args) {
LinkedList<String> queue = new LinkedList<>();
queue.add("Task 1");
queue.add("Task 2");
queue.addFirst("Urgent Task");
while (!queue.isEmpty()) {
System.out.println(queue.removeFirst());
}
}
}
3. Vector 구현
import java.util.Vector;
public class VectorExample {
public static void main(String[] args) {
Vector<Integer> numbers = new Vector<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
for (int num : numbers) {
System.out.println(num);
}
}
}
'공부 > 자바(Java)' 카테고리의 다른 글
Java) Queue란? (큐 간단 설명, 사용법, 예제) (3) | 2025.04.05 |
---|---|
Java) Stack이란? (간단 설명, 사용법, 예시) (0) | 2025.04.05 |
Java) HashMap, TreeMap, LinkedHashMap이란? (설명, 사용법, 예시) (0) | 2025.04.04 |
Java) Map 자료구조 간단 설명 (0) | 2025.04.04 |
JAVA) 경로 안의 파일들 목록 텍스트 파일로 저장하기 (2) | 2025.03.24 |