Skip to main content

[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()

정의된 클래스

java.util.List 인터페이스

java.util.Arrays 클래스

실제 구현 클래스

ArrayList.SubList등 내부 클래스

Arrays.ArrayList (java.util.ArrayList와 다름)

크기 조정 가능 여부

O (원본 리스트가 ArrayList인 경우)

❌ (add/remove 불가)

원본과 연동 여부

✅ (뷰, 연동됨)

✅ (원본 배열과 연동됨)

image.png


4. 주의할 점

주의 사항

설명

원본 리스트 변경 시 subList()도 함께 영향 받음

(뷰이기 때문에) 원본 리스트가 바뀌면 subList() 결과도 바뀜

ConcurrentModificationException 주의

원본 리스트와 subList()동시에 수정하면 예외 발생 가능

깊은 복사 원할 땐 new ArrayList<>(subList(...))

안전한 복사 필요 시에는 복사해서 쓰는 것이 좋음


5. 결론

  • 읽기 전용 슬라이싱 / 범위 작업: subList() 매우 유용
  • 요소 삭제/추가 필요 없음 + 범위 한정 작업: 코테에서 딱 좋음
  • 조작하려면 복사해서 사용하자new ArrayList<>(list.subList(from, to))