자바 언어·플랫폼 용어 사전
컬렉션

subList

원본 리스트의 일부를 들여다보는 뷰. 복사본이 아니라서 양쪽 수정이 서로 보이고, 원본이 구조적으로 바뀌면 예외가 난다.

subList(from, to)새 리스트를 만들지 않는다. 원본을 가리키는 창을 돌려준다.

세 가지 결과

List<String> all  = new ArrayList<>(List.of("a","b","c","d","e"));
List<String> part = all.subList(1, 3);      // [b, c]

part.set(0, "B");        // ① 뷰를 고치면 원본이 바뀐다 → all = [a, B, c, d, e]
all.add("f");            // ② 원본을 구조적으로 바꾸면
part.get(0);             //    뷰는 무효가 된다 → ConcurrentModificationException

원본이 GC 되지 않는다. 뷰가 원본 리스트를 참조하고 있어, 원소 두 개짜리 조각을 들고 있다고 생각해도 뒤에 백만 개짜리 배열이 통째로 살아남는다.

왜 이렇게 설계했나

복사를 안 하기 때문에 O(1) 이다. list.subList(a,b).clear() 로 구간을 통째로 지우는 관용구도 이 성질 덕분에 성립한다. 비용을 안 치르는 대신 원본과 운명을 공유한다.

안전하게 쓰는 법

List<String> copy = new ArrayList<>(all.subList(1, 3));   // 독립 스냅숏

메서드 밖으로 넘길 값이라면 반드시 복사한다. 뷰를 반환하는 API는 "내 내부를 만질 수 있는 창"을 넘기는 것과 같다.

같은 성질을 가진 것들

Collections.unmodifiableList(읽기 전용 뷰), Map.keySet()·values()·entrySet() 도 모두 뷰다. keySet().remove(k) 가 맵에서 실제로 지워지는 이유가 그것이다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 컬렉션·예외·리소스