개요
자바의 참조 자료형에 대해 계속해서 정리하고 있다. 저번에 String에 대해 정리했으니, 오늘은 ArrayList에 대해 정리해볼 계획이다.
1. ArrayList란
개발 중 데이터를 관리하고 저장할 때 많이 쓰이는 컬렉션(Collection) 자료 구조 중 하나가 바로 ArrayList이다.
ArrayList는 자바 컬렉션 프레임워크에 속하는 클래스이고, 기본적으로 List 인터페이스를 구현한 동적 배열 자료구조이다.
ArrayList는 내부적으로 Object[] 타입을 사용해서 요소를 저장한다.
초기 생성 시에는 빈 배열 혹은 기본 용량을 가진 배열로 시작하며, 요소를 추가하다 더 많은 공간이 필요해진다면, 새로운 배열을 생성하고 기존 데이터를 복사한 뒤 참조를 교체하는 방식으로해서 용량을 늘린다.
-> Doubling을 사용하는데, ArrayList에 배열이 다 차게 되면 2배로 늘리고, 기존 데이터를 복사해오는 작업이다.
용량(capacity) 및 크기(size)
size
-> 현재 저장된 요소의 개수를 의미한다.
capacity
-> 내부적으로 관리하는 배열의 길이로, 크기보다 용량이 작아지진 않고, 필요할 때 더 큰 용량을 가진 배열로 확장된다.
2. 특징
1) 인덱스를 통한 빠른 접근
-> 내부적으로 배열을 사용하기 때문에 특정 인덱스의 요소에 접근하는 데 O(1) 시간복잡도를 가진다.
2) 동적 크기 조절
-> 배열과 다르게, 원소를 추가하면 내부적으로 크기가 자동으로 확장된다.
3) 순서 유지
-> 삽입한 순서를 유지하며, 인덱스를 기반으로 정렬된 형태의 자료 구조 이다.
4) 제네릭 활용
-> ArrayList는 제네릭을 지원하므로, 사용할 때 명시적인 타입 파라미터를 통해 타입 안정성을 보장할 수 있다.
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(20);
// numbers.add("Hello"); // 컴파일 에러 발생
5) 시간 복잡도
-> 인덱스 접근은 O(1)의 시간 복잡도를 가지고,
-> 맨 뒤에 요소를 추가시에는 평균적으로 O(1)이지만,
용량을 확장해야 할 때는 copy작업이 들어가기 때문에 O(n)이 발생할 수 있다.
-> 중간 삽입 및 삭제에서 copy가 필요하기 때문에 O(n)이다.
6) 타입으로 객체만 적용 가능
-> 객체로 데이터를 다루기 때문에 적은양의 데이터를 쓸 경우에는 배열에 비해 차지하는 메모리가 커진다.
-> 예로, Integer를 32bit JVM환경에서 사용할 때, 객체의 헤더(8Byte), 원시 필드(4Byte), 패딩(4Byte)로 '최소 16Byte의 크기'를 차지한다. 게다가 이 객체 데이터를 주소로 연결하기 때문에 16 + a가 된다.
3. ArrayList 적용
ArrayList의 활용을 위해서는 java.util.ArrayList를 import해야 한다.
import java.util.ArrayList;
import java.util.List;
public class ArrayListExample {
public static void main(String[] args) {
// 타입 파라미터로 관리할 데이터 타입 지정 (예: String)
List<String> fruits = new ArrayList<>();
//초기 할당
List<String> fruits2 = new ArrayList<>(1000);
}
}
ArrayList 또는 List를 통해 위의 코드와 같이 선언해줄 수 있고, 초기 할당도 가능하다!
3-1. 메소드
(1) 추가
메소드 | 설명 | 예제 |
boolean add(E e) | 리스트 뒤에 요소를 추가 | list.add("Apple"); |
void add(int index, E element) | 특정 인덱스 위치에 요소를 삽입 (뒤의 요소는 밀림) | list.add(1, "Mango"); |
boolean addAll(Collection<? extends E> c) | 다른 컬렉션 c의 모든 요소를 리스트 끝에 추가 | list.addAll(otherList); |
boolean addAll(int index, Collection<? extends E> c) | 지정한 인덱스 위치에 다른 컬렉션의 모든 요소 삽입 | list.addAll(2, otherList); |
(2) 접근 및 조회
메소드 | 설명 | 예제 |
E get(int index) | 인덱스를 통한 요소 접근 | E elem = list.get(0); |
int size() | 리스트 내 요소 개수 반환 | int count = list.size(); |
boolean isEmpty() | 빈 리스트인지 확인 | if (list.isEmpty()) { ... } |
boolean contains(Object o) | 특정 요소 포함 여부 확인 | list.contains("Apple"); |
int indexOf(Object o) | 특정 요소의 첫 등장 인덱스 | int idx = list.indexOf("Apple"); |
int lastIndexOf(Object o) | 특정 요소의 마지막 등장 인덱스 | int lastIdx = list.lastIndexOf("Apple"); |
(3) 수정
메소드 | 설명 | 예제 |
E set(int index, E element) | 지정 인덱스의 요소를 다른 값으로 교체 | list.set(0, "Peach"); |
(4) 삭제
메소드 | 설명 | 예제 |
boolean remove(Object o) | 특정 객체의 첫 등장 요소 제거 | list.remove("Apple"); |
E remove(int index) | 인덱스로 요소 제거, 제거된 요소 반환 | E removed = list.remove(0); |
boolean removeAll(Collection<?> c) | 지정 컬렉션에 포함된 모든 요소를 제거 | list.removeAll(otherList); |
void clear() | 모든 요소 제거 | list.clear(); |
(5) 부분 리스트
메소드 | 설명 | 예제 |
List<E> subList(int fromIndex, int toIndex) | 지정 범위의 부분 리스트 반환 (원본과 연동됨) | List<E> sub = list.subList(1,3); |
Object[] toArray() | 전체 요소를 Object[] 배열로 반환 | Object[] arr = list.toArray(); |
<T> T[] toArray(T[] a) | 타입 지정 배열로 변환, a 크기가 부족하면 새 배열 생성 | String[] arr = list.toArray(new String[0]); |
(6) 용량 관리(Capacity Management)
메소드 | 설명 | 예제 |
void ensureCapacity(int minCapacity) | 지정한 최소 용량 확보 | list.ensureCapacity(1000); |
void trimToSize() | 용량을 현재 요소 개수에 맞게 줄임 | list.trimToSize(); |
'Language > java' 카테고리의 다른 글
[Java] HashMap이란 (0) | 2024.12.16 |
---|---|
[Java] String이란 (0) | 2024.12.12 |
[Java] 자료형 개요 & 숫자 (0) | 2024.01.24 |
[Java] 자바 시작하기 (2) | 2024.01.11 |