이번 글에서는 List가 제공하는 subList라는 메서드에 대해서 살펴보자.
List<E> subList(int fromIndex, int toIndex);
무엇에 쓰는 물건인고?
이름 그대로 어떤 리스트의 구성 요소 중 fromIndex에서 toIndex까지의 요소를 반환해준다. 예를 들어
List<Integer> nums = new ArrayList<Integer>();
for(int i=0; i<10; i++) {
nums.add(i);
}
List<Integer> sub = nums.subList(2, 5);
System.out.printf("nums: %s, sub: %s%n",nums, sub);
위 코드의 결과는 다음과 같다.
nums: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], sub: [2, 3, 4]
너무나 쉽게 쪼가리를 구할 수 있으며 fromIndex는 inclusive, toIndex는 exclusive 인 것을 알 수 있다. (이런 메서드는 대부분 다 그렇다..)
쉬운데 왜?
그런데 정말 재밋는 점이 있다.
The returned list is backed by this list, so non-structuralchanges in the returned list are reflected in this list, and vice-versa.
반환된 리스트는 요소들만 따로 분리해서 만든게 아니라 여전히 연결되어있기 때문에 상호간에 영향을 준다는 것이다.
List<Integer> nums = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
nums.add(i);
}
List<Integer> sub = nums.subList(2, 5);
System.out.printf("nums: %s, sub: %s%n", nums, sub);
sub.add(100); // sublist에 100 추가
sub.remove(0); // sublist의 0번 요소 즉 2 삭제
System.out.printf("nums: %s, sub: %s%n", nums, sub);
즉 위와 같은 코드에서 sublist에 값을 추가하고 삭제했는데 실행 결과를 보면 원본인 List의 구성 요소 역시 변경된 것을 알 수 있다.
nums: [0, 1, 3, 4, 100, 5, 6, 7, 8, 9], sub: [3, 4, 100]
아주 신기하다 ㅎ
또하나 신경쓸 부분
또 하나 신경 쓸 부분은 subList를 사용하다가 원본 리스트를 변경하게 되면 subList는 기존의 sublist는 더 이상 사용할 수 없게 된다.
nums.add(99);
System.out.printf("nums: %s%n", nums); // nums: [0, 1, 3, 4, 100, 5, 6, 7, 8, 9, 99]
System.out.printf("sub: %s%n", sub); // java.util.ConcurrentModificationException 발생
런타임 예외가 발생하니 실수하지는 않겠지만 주의가 필요한 부분이다.