스스로 크기를 조절하는 리스트
자바의 일반 배열은 길이가 고정되어 있습니다. 칸 열 개로 정하면 영원히 열 개입니다. ArrayList는 java.util이 제공하는 크기 가변 대안으로, 추가하면 늘어나고 삭제하면 줄어들며, 리스트로 실제로 하는 작업에 필요한 편리한 메서드를 갖추고 있습니다.
꺾쇠 괄호 안의 타입 - List<String> - 에 주목하세요. 이는 이 리스트가 String 값을 담는다는 것을 컴파일러에 알려 줍니다. 오른쪽의 <>("다이아몬드")는 같은 타입을 반복하지 않고도 자바가 추론하게 해 줍니다. 그리고 java.util.ArrayList를 임포트한다는 점에 유의하세요. 기본으로는 사용할 수 없습니다.
List로 선언하고 ArrayList로 생성하기
변수는 구체적인 ArrayList가 아니라 List 인터페이스 타입으로 선언된 모습을 거의 항상 보게 됩니다:
List<String> names = new ArrayList<>();
이는 규칙이 아니라 좋은 습관입니다. List 인터페이스에 맞춰 코딩하면 나머지 코드는 어떤 리스트 구현을 썼는지 신경 쓰지 않으므로, 나중에 그 코드를 건드리지 않고도 다른 구현으로 바꿀 수 있습니다. 일상적인 사용에서는 둘의 동작이 같습니다.
추가, 가져오기, 변경
add(value)는 끝에 추가합니다.add(index, value)는 어떤 위치에 삽입하며, 뒤따르는 요소들을 오른쪽으로 밀어냅니다.get(index)는 어떤 위치의 요소를 읽습니다(0부터 시작).set(index, value)는 기존 요소를 덮어씁니다.
인덱스는 0부터 시작하며, 범위를 벗어난 인덱스로 get을 호출하면 IndexOutOfBoundsException이 발생합니다.
요소 삭제하기
리스트가 Integer를 담을 때 흔히 빠지는 함정이 있습니다. remove(int)는 "인덱스로 삭제"이고 remove(Object)는 "값으로 삭제"이므로:
List<Integer> nums = new ArrayList<>(List.of(10, 20, 30));
nums.remove(1); // 인덱스 1을 삭제 -> 값 20
nums.remove(Integer.valueOf(20)); // 값 20을 삭제
"이 인덱스를 삭제"가 아니라 "이 값을 삭제"하려는 경우에는 값을 Integer.valueOf(...)로 감싸세요.
크기, contains, 인덱스 조회
List.of(...)는 빠르게 불변 리스트를 만듭니다. 이를 ArrayList 생성자에 넘기면 그 값들로 채워진 가변 복사본을 얻습니다.
ArrayList 반복하기
가장 깔끔한 반복은 향상된 for("for-each")입니다:
인덱스도 필요할 때는 size()와 get(i)를 사용하는 카운터 기반 반복을 사용하세요:
한 가지 규칙: for-each 반복이 리스트를 순회하는 동안 그 리스트에 요소를 추가하거나 삭제하지 마세요 - ConcurrentModificationException이 발생합니다. 일치하는 항목을 안전하게 삭제하려면 removeIf를 사용하세요:
정렬
Collections.sort는 자연 순서(문자열은 알파벳순, 숫자는 수치순)를 사용해 리스트를 제자리에서 정렬합니다:
사용자 정의 순서가 필요하면 list.sort(...)에 Comparator를 넘기세요 - 예를 들어 길이로 정렬하려면 names.sort(Comparator.comparingInt(String::length))입니다.
ArrayList는 기본형이 아니라 객체를 담는다
ArrayList<int>라고 쓸 수 없습니다. 제네릭은 객체 타입에서만 동작하므로 래퍼 클래스인 Integer, Double, Boolean 등을 사용하세요:
자바의 오토박싱이 int와 Integer 사이 변환을 대신 처리해 주므로 자연스럽게 읽힙니다 - 다만 리스트 자체는 Integer 객체를 저장한다는 점만 기억하세요.
다음: HashMap
ArrayList는 순서와 위치가 중요할 때 알맞은 도구입니다. 키로 값을 찾아야 할 때 - 사용자명에서 사용자로, 상품 코드에서 가격으로 - 에는 HashMap이 필요하며, 그것이 다음 페이지입니다.
자주 묻는 질문
자바에서 ArrayList는 어떻게 생성하나요?
요소 타입을 꺾쇠 괄호 안에 적어 선언하고 생성자를 호출합니다: ArrayList<String> names = new ArrayList<>();. 오른쪽의 <>(다이아몬드)는 자바가 타입을 추론하게 해 줍니다. 보통 변수는 List 인터페이스 타입으로 선언합니다: List<String> names = new ArrayList<>();.
자바에서 배열과 ArrayList의 차이는 무엇인가요?
일반 배열은 생성할 때 정해지는 고정 길이를 가지며 int 같은 기본형을 담을 수 있습니다. ArrayList는 요소를 추가하고 삭제함에 따라 자동으로 늘어나고 줄어들며, 객체만 담을 수 있고(그래서 int는 Integer가 됩니다), add, remove, contains, size 같은 메서드를 제공합니다. 크기가 고정된 기본형 데이터에는 배열을, 크기가 바뀔 때는 ArrayList를 사용하세요.
ArrayList에서 요소를 어떻게 삭제하나요?
위치로 삭제하려면 remove(index)를, 일치하는 첫 번째 요소를 삭제하려면 remove(object)를 호출합니다. Integer 리스트에서는 주의해야 합니다: list.remove(2)는 인덱스 2를 삭제하지만, list.remove(Integer.valueOf(2))는 값 2를 삭제합니다. 반복 중에 삭제하려면 ConcurrentModificationException을 피하기 위해 Iterator의 remove()나 removeIf(...)를 사용하세요.