[Java] subList(from, to) vs Arrays.asList
1. subList(from, to)
- 정의 위치:
java.util.List
인터페이스의 default method - 반환 타입:
List<E>
(실제로는 내부 클래스SubList
) - 실제 구현 클래스:
ArrayList
내부의SubList
클래스가 대표적
List<String> list = new ArrayList<>();
List<String> sub = list.subList(1, 3); // 이건 list의 '뷰(view)'
subList()
는 원본 리스트의 특정 범위만을 얕은 복사 없이 참조한다.- 내부 클래스인
ArrayList.SubList
가 반환되며, 이는 원본 리스트의 범위 일부를 가리키는 뷰(view)이다. - 따라서 원본 리스트 변경 시
subList()
도 영향을 받는다.
List<String> list = new ArrayList<>(List.of("a", "b", "c", "d"));
List<String> sub = list.subList(1, 3); // ["b", "c"]
list.set(1, "x");
System.out.println(sub); // [x, c] ← 반영됨
2. Arrays.asList(...)
- 정의 위치:
java.util.Arrays
클래스의 static 메서드 - 반환 타입:
List<T>
(실제로는java.util.Arrays.ArrayList
) ← 이건 java.util.ArrayList와 다른 클래스! - 내부 클래스:
java.util.Arrays.ArrayList
(고정 크기)
List<String> list = Arrays.asList("a", "b", "c");
- 이 리스트는 고정 크기입니다.
add()
나remove()
호출 시UnsupportedOperationException
발생한다. - 단, 요소의 읽기와 수정(set)은 가능하다.
- 내부 구현은
Object[]
배열을 감싼 래퍼이며, 원본 배열을 직접 참조한다.
String[] arr = {"a", "b", "c"};
List<String> list = Arrays.asList(arr);
arr[0] = "x";
System.out.println(list); // [x, b, c] ← 반영됨
3. 비교
항목 | subList() | Arrays.asList() |
---|---|---|
정의된 클래스 |
|
|
실제 구현 클래스 |
|
|
크기 조정 가능 여부 | O (원본 리스트가 ArrayList인 경우) | ❌ (add/remove 불가) |
원본과 연동 여부 | ✅ (뷰, 연동됨) | ✅ (원본 배열과 연동됨) |
4. 주의할 점
주의 사항 | 설명 |
---|---|
원본 리스트 변경 시 | (뷰이기 때문에) 원본 리스트가 바뀌면 |
| 원본 리스트와 |
깊은 복사 원할 땐 | 안전한 복사 필요 시에는 복사해서 쓰는 것이 좋음 |
5. 결론
- 읽기 전용 슬라이싱 / 범위 작업:
subList()
매우 유용 - 요소 삭제/추가 필요 없음 + 범위 한정 작업: 코테에서 딱 좋음
- 조작하려면 복사해서 사용하자 →
new ArrayList<>(list.subList(from, to))