List 컬렉션은 객체를 일렬로 늘어놓은 구조로 객체를 인덱스로 관리하기 때문에 객체를 저장하면 자동으로 인덱스가 부여되고, 인덱스로 객체를 검색, 삭제할 수 있는 기능이 제공된다. 또 List 컬렉션은 객체 자체를 저장하는 것이 아닌 객체의 주소값을 참조하며, 비슷한 구조를 갖고 있는 Set 인터페이스와 다르게 동일한 객체를 저장하는 것을 허용하는데 이 경우 동일한 객체의 주소값을 참조한다.
List 컬렉션의 종류로는 ArrayList, Vector, LinkedList가 있다.
ArrayList는 List 컬렉션 인터페이스를 구현한 클래스이다. 컬렉션 프레임워크에서 가장 자주 사용되며 List 컬렉션처럼 인덱스로 객체를 관리한다. 일반 배열과 ArrayList는 인덱스로 객체를 관리한다는 점에서 유사하나, 배열은 생성과 함께 크기가 고정되고, ArrayList는 크기를 동적으로 관리할 수 있다는 점에서 차이가 있다.
// ArrayList 생성
List<String> list = new ArrayList<>();
// String 타입의 객체를 저장하는 ArrayList
// 기본 저장 용량은 10
List<String> list = new ArrayList<>(100);
// 저장 용량 100을 가지고 String 타입의 객체를 저장하는 ArrayList
// 객체 생성
List<String> list = new ArrayList<>();
// 객체 추가
list.add("Java");
list.add("Python");
list.add("Kotlin")
int size = list.size(); // 객체 총 개수 (3)
String str = list.get(index); // index번의 객체 값 얻기
list.remove(index); // index번의 객체 삭제
이처럼 인덱스를 이용해 객체를 관리 하기 때문에 객체 삭제와 삽입이 빈번하게 일어나는 경우 ArrayList를 사용하지 않는 것이 좋다.
앞서 객체 삭제와 삽입이 빈번하게 일어날 때 LinkedList를 사용하는 것이 좋은 방법이 될 수도 있는데 내부 구조가 ArrayList와 다르기 때문인데 LinkedList는 데이터와 포인터를 별도로 가지고 있다. 그래서 객체를 추가하거나 삭제하면 앞뒤 링크만 변경되고 나머지 링크는 변경되지 않는다.
LinkedList<String> list = new LinkedList<>();
list.add("Java");
list.add("Python");
list.add(1, "Kotlin"); // index 1에 데이터 추가
// 출력 시 [Java, Kotlin, Python]
list.set(0, "JavaScript"); // set()메서드를 이용해 값 변경
// 출력시 [JavaScript, Kotlin, Python]
인덱스가 없기 때문에 특정 요소에 접근하기 위해서는 순차 탐색이 필요하여 속도가 떨어진다는 단점이 있으나 앞서 코드와 같이 데이터의 추가, 삭제, 관리에 있어 용이하여 탐색 또는 정렬을 자주 하는 경우 ArrayList, 데이터의 변경이 많은 경우 LinkedList를 사용하는 것이 좋다.