List인터페이스는 중복을 허용하면서 저장순서가 유지되는 컬렉션을 구현할 때 사용한다.
ArrayList와 LinkedList는 List인터페이스의 구현체이다. 이 둘의 차이는 어떤 것들이 있을까?
구조적인 차이
ArrayList :
내부적으로 Object 배열을 생성하여 인덱스 방식으로 데이터에 접근한다.
LinkedList :
리스트의 요소는 데이터와 다음 요소에 대한 참조를 가지고 있다. 이 요소를 노드 라고 한다. 다음 노드에 대한 참조를 계속 참조하여 데이터에 접근한다.
(참고 : 실제로 LinkedList 클래스는 낮은 접근성을 높이기 위해 DoublieLinkedList로 구현되어 있다.)
크기 변경에 대한 오버헤드
ArrayList :
배열은 크기를 정하여 크기 만큼의 공간을 할당하고 초기화를 한다. 따라서 공간이 부족하면 더 큰 배열을 만들어서 배열의 요소들을 복사한다. 기존에 존재하던 배열을 버리고 새로운 배열을 생성하고 요소를 복사하는 과정 때문에 크기 변경에 의한 오버헤드가 크다.
LinkedList :
새로운 노드를 만들어서 이전 노드의 참조가 새로 만든 노드를 가리키도록 한다. ArrayList와 달리 노드를 생성하여 이를 연결만 하기 때문에 크기 변경에 대한 오버헤드가 적다.
데이터 조회
ArrayList :
인덱스를 바로 접근하기 때문에 조회가 빠르다.
LinkedList :
순차적으로 다음 노드에 대한 참조를 반복하며 탐색하기 때문에 느리다.
데이터 삽입, 삭제
ArrayList :
배열로 구현되어있기 때문에 배열의 마지막에 데이터를 추가하는 것은 빠르다. 하지만 중간에 데이터를 추가하려면 데이터들을 한 칸씩 뒤로 밀어서 삽입을 해야 한다. 배열의 요소들을 재배치 해야 하기 때문에, 데이터를 중간에 추가하는 경우에는 느리다. (삭제는 그 반대의 과정이다.)
LinkedList :
삽입 과정은 삽입할 위치의 다음 노드를 참조하는 노드를 생성하고 이전 노드가 참조하도록 한다. 각 노드간의 연결만 변경하기 되기 때문에 중간에 데이터를 추가하더라도 빠르다. (삭제는 삭제할 노드의 이전 노드가 삭제할 노드의 다음 노드를 참조하도록 한다.)
그럼 언제 어떤 List를 사용해야 하는가?
ArrayList :
데이터를 리스트의 뒤에서부터 순차적으로 삭제하는 경우, 순차적으로 데이터를 초기화 하는 경우, List의 크기가 정적일 경우 사용하는 것이 좋다.
LinkedList :
중간에 데이터를 추가/삭제하는 경우, List의 크기가 동적일 경우 사용하는 것이 좋다.
'개발 > JAVA' 카테고리의 다른 글
벤치마크로 병렬 스트림 성능 확인하기 (0) | 2023.04.08 |
---|---|
JDK 21의 새로운 개념 JEP 431: Sequenced Collections (0) | 2023.03.21 |
일급 컬렉션 (First Class Collection) 이란? (0) | 2022.12.03 |
[JAVA] Enum 이란? (0) | 2022.11.10 |
[우아한 테크코스 프리코스] 테스트 코드 분석(AssertJ, JUnit5) (0) | 2022.11.09 |