📝 Java ArrayList
1. ArrayList란?
- Java의 대표적인 List 컬렉션 클래스
- 배열과 달리 크기가 가변적이며, 데이터를 추가/삭제할 수 있다.
- 순서(인덱스) 보장 + 중복 허용
- java.util 패키지에 포함되어 있음
- 형식 : ArrayList list = new ArrayList();
- 삽입시 add() 메서드 이용!
- 추출시 get() 메서드 이용!
| 구분 | 배열(Array) | ArrayList |
| 크기 | 고정 | 가변 (자동 확장) |
| 타입 | 기본형 + 객체 | 객체만 저장 가능 (기본형은 Wrapper 필요) |
| 기능 | 단순 데이터 저장 | 추가, 삭제, 검색, 정렬 등 다양한 메서드 제공 |
2. ArrayList 기본 예제
import java.util.ArrayList;
import java.util.Scanner;
public class Ex03_ArrayList {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
// 데이터 추가
al.add("펭구");
al.add("모코코");
al.add("코니");
al.add("배불뚝이");
// 크기 확인
System.out.println("size :" + al.size()); // 4
System.out.println(al); // [펭구, 모코코, 코니, 배불뚝이]
// 인덱스로 접근
System.out.println("2번째 값 : " + al.get(1)); // 모코코
// 중간에 데이터 삽입
al.add(1, "꿀벌 배불뚝이");
System.out.println(al); // [펭구, 꿀벌 배불뚝이, 모코코, 코니, 배불뚝이]
// 값의 위치 찾기
System.out.println(al.indexOf("꿀벌 배불뚝이")); // 1
System.out.println(al.lastIndexOf("꿀벌 배불뚝이")); // 1
// 포함 여부 확인
System.out.println(al.contains("판다 배불뚝이")); // false
// 값 삭제
al.remove("코니");
System.out.println(al);
// 전체 초기화
al.clear();
System.out.println(al); // []
System.out.println(al.size()); // 0
}
}
3. 실행 결과
size :4
[펭구, 모코코, 코니, 배불뚝이]
2번째 값 : 모코코
[펭구, 꿀벌 배불뚝이, 모코코, 코니, 배불뚝이]
1
1
false
[펭구, 꿀벌 배불뚝이, 모코코, 배불뚝이]
[]
0
4. 주요 메서드 정리
| 메서드 | 설명 | |
| 추가/수정 | add(E e) | 데이터 추가 |
| add(int index, E e) | 특정 위치에 삽입 | |
| set(int index, E e) | 리스트 안의 특정 위치에 있는 값을 교체(수정) | |
| 조회 | get(int index) | 인덱스로 값 가져오기 |
| contains(Object o) | 값 포함 여부 확인 | |
| indexOf(Object o) | 값 위치 검색 (앞에서부터) | |
| lastIndexOf(Object o) | 값 위치 검색 (뒤에서부터) | |
| isEmpty() | 리스트가 비어있는지 확인 | |
| size() | 요소 개수 반환 | |
| 삭제 | remove(Object o) | 특정 객체 삭제 (첫 번째로 발견된 것만) |
| remove(int index) | 해당 인덱스 삭제 | |
| clear() | 전체 삭제 | |
| 변환 | toArray() | 배열로 변환 |
| 반복/스트림 | iterator() | Iterator 객체 반환 |
| listIterator() | ListIterator 객체 반환 (양방향 탐색 가능) |
👉 보통 시험/실무에서 제일 많이 쓰는 건
add, get, set, remove, size, contains, clear 정도
5. 객체만 저장 가능 (Wrapper 클래스 & 오토박싱)
- ArrayList에는 객체만 저장 가능
- 기본형(int, double 등)은 Wrapper 클래스로 변환해야 한다.
- Java 5부터는 오토박싱/언박싱 덕분에 기본형처럼 사용 가능
오토박싱 / 오토언박싱 예제
ArrayList<Integer> numbers = new ArrayList<>();
// 오토박싱 (int → Integer 자동 변환)
numbers.add(10); // int 값이 자동으로 Integer 객체로 변환되어 들어감
numbers.add(20);
// 오토언박싱 (Integer → int)
int value = numbers.get(1); // list.get(1)은 원래 Integer 객체
System.out.println(value); // 20
❗기본 개념
- 오토박싱: int → Integer, double → Double 자동 변환
- 오토언박싱: Integer → int, Double → double 자동 변환
- ArrayList 같이 객체만 저장 가능한 컬렉션에서 기본형을 다룰 때 아주 편리하다.
6. Arraylist 기본 정리
- ArrayList는 순서 O, 중복 O, 크기 가변적
- 배열보다 유연하고 편리하게 데이터 관리 가능
- 실무에서 가장 많이 쓰이는 List 컬렉션 클래스
🌈 제네릭 <> 안에는 왜 클래스 타입만 올 수 있을까?
1. 제네릭(Generic) 기본
- ArrayList<E> 처럼 <E> 안에는 자료형(Type) 을 지정할 수 있다.
- 단, 이 자리에는 기본형(Primitive) 이 아니라 클래스 타입(참조형) 만 들어올 수 있다.
ArrayList<int> list1; // ❌ 오류: 기본형은 올 수 없음
ArrayList<Integer> list2; // ✅ 가능: Wrapper 클래스(Integer)는 참조형
ArrayList<String> list3; // ✅ 가능: String은 클래스
ArrayList<Music> list4; // ✅ 가능: 내가 만든 Music도 클래스
2. 기본형 vs 참조형
| 구분 | 기본형(Primitive) | 참조형(Reference / 클래스) |
| 예시 | int, double, char, boolean | String, Integer, Double, Music |
| 저장 방식 | 값 자체 저장 | 객체의 주소(참조) 저장 |
| 객체 여부 | ❌ 객체 아님 | ✅ 클래스 기반 객체 |
| ArrayList 사용 | 불가능 (ArrayList<int>) | 가능 (ArrayList<Integer>, ArrayList<Music>) |
3. String과 Integer도 클래스다!
- String : 문자열을 다루는 클래스 (자바 표준 라이브러리에 포함)
- Integer : int를 객체로 감싼 Wrapper 클래스
- Music : 사용자가 정의한 클래스
즉, String, Integer, Music 모두 참조형 클래스 타입이므로 제네릭 <T> 자리에 올 수 있다.
// String도 클래스라서 가능
ArrayList<String> list1 = new ArrayList<String>();
// Integer도 클래스라서 가능 (Wrapper)
ArrayList<Integer> list2 = new ArrayList<Integer>();
// Music도 내가 만든 클래스니까 가능
ArrayList<Music> list3 = new ArrayList<Music>();
list3.add(new Music("제목", "가수", 1500)); // 객체 저장
4. 왜 기본형은 안 될까?
- 제네릭은 내부적으로 객체(참조형) 만 다룰 수 있도록 설계되어 있다.
- 기본형은 객체가 아니기 때문에 ArrayList<int> 같은 건 불가능하다.
- 대신 Wrapper 클래스 + 오토박싱을 사용해서 해결한다.
ArrayList<Integer> nums = new ArrayList<>();
nums.add(10); // int → Integer (오토박싱)
int n = nums.get(0); // Integer → int (오토언박싱)
5. 제네릭 <> 정리
- 제네릭 <> 안에는 반드시 클래스 타입(참조형) 만 들어갈 수 있다.
- 그래서 ArrayList<Music> 처럼 내가 만든 클래스도 타입으로 지정 가능하다.
- String, Integer 역시 모두 클래스 타입이다.
- 기본형은 직접 못 쓰고 → Wrapper 클래스(Integer, Double …)를 사용해야 한다.
ArrayList<Music> 예시1
import java.util.ArrayList;
import java.util.Scanner;
// 곡 정보를 담는 Music 클래스
class Music {
private String title; // 노래 제목
private String singer; // 가수명
private int price; // 가격
// 생성자: 객체 생성 시 제목/가수/가격을 한 번에 초기화
public Music(String title, String singer, int price) {
this.title = title;
this.singer = singer;
this.price = price;
}
// toString() 오버라이딩: 객체 출력 시 보기 좋게 문자열 반환
@Override
public String toString() {
return "노래 제목 : " + title + ", 가수 : " + singer + ", 가격 : " + price;
}
}
public class Ex07_ArrayList {
public static void main(String[] args) {
// 여러 Music 객체를 저장할 수 있는 ArrayList 생성
ArrayList<Music> list = new ArrayList<Music>();
Scanner sc = new Scanner(System.in); // 사용자 입력을 받기 위한 Scanner
String title, singer, retry; // 문자열 입력값 저장용 변수
int price; // 정수 입력값 저장용 변수
// do~while : 최소 1번은 실행되는 반복문
do {
System.out.println("제목 입력");
title = sc.next(); // 제목 입력 받기 (공백 포함하려면 nextLine() 사용)
System.out.println("가수명 입력");
singer = sc.next(); // 가수명 입력
System.out.println("가격 입력");
price = sc.nextInt(); // 가격 입력 (정수)
// 입력받은 값으로 Music 객체를 생성해 ArrayList에 추가
list.add(new Music(title, singer, price));
System.out.println("계속(y/n)");
retry = sc.next(); // 계속 여부 입력
if(retry.equals("n")) { // "n" 입력 시 반복 종료
System.out.println("프로그램을 종료합니다.");
break;
}
} while(true); // 무한 루프, 내부에서 break로 탈출
// ArrayList에 저장된 Music 객체 전체 출력
int i;
for(i = 0; i < list.size(); i++) {
Music s = list.get(i); // i번째 Music 객체 꺼내기
System.out.println(s); // Music.toString() 호출 → 곡 정보 출력
}
// 최종 목표: 입력한 데이터를 Music 객체로 만들어 ArrayList에 저장 후 전체 출력
}
}
ArrayList<Card> 예시2
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Set;
class Card{
private String name;
private String tel;
public Card(String name, String tel) {
super();
this.name = name;
this.tel = tel;
}
public String toString() {
return name + "\t\t" + tel;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
}//Card
public class Ex06_이정륜 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<Card> list = new ArrayList<Card>();
String name;
String tel ;
int menu;
do {
System.out.print("1.명함추가 2.명함삭제 3.명함수정 4.명함보기 5.종료 :");
boolean findname = false;
menu = sc.nextInt();
switch (menu) {
case 1:
// 1. 명함추가
System.out.print("등록할 이름을 입력하세요 :");
name = sc.next();
System.out.print("등록할 전화번호를 입력하세요. :");
tel = sc.next();
Card m = new Card(name, tel);
list.add(m); // 명함 추가
break;
case 2:
// 2. 명함 삭제
System.out.print("삭제할 이름을 입력하세요 :");
name = sc.next();
for(int i=0; i<list.size(); i++) {
Card c = list.get(i);
if(c.getName().equals(name)) {
list.remove(i);
System.out.println(name +" 삭제되었습니다.");
findname = true;
}
}if(findname == false) {
System.out.println("존재하지 않는 이름입니다.");
}
break;
case 3:
// 3.명함수정
System.out.print("전화번호를 수정할 이름을 입력하세요 :");
name = sc.next();
for(int i=0; i<list.size(); i++) {
Card c = list.get(i);
if(c.getName().equals(name)) {
System.out.print("새로운 전화번호를 입력하세요. :");
tel = sc.next();
list.get(i).setTel(tel);
// set을 이용하여 변경
// Card c6 = new Card(name, tel);
// list.set(i, c6);
System.out.println("수정되었습니다.");
findname = true;
}
}if(findname == false) {
System.out.println("이름을 잘못입력하셨습니다.");
}
break;
case 4:
// 4.명함보기
System.out.println("이름" + "\t\t" + "전화번호");
for(Card cv : list) {
System.out.println(cv.getName() + "\t\t" + cv.getTel());
// System.out.println(cv);
}
if(list.isEmpty()) {
System.out.println("등록된 명함 없음");
}
break;
case 5:
// 5.종료
System.out.println("프로그램을 종료합니다");
return;
default: System.out.println("잘못입력하셨습니다.");
}
}while(true);
}
}
/*
1.명함추가 2.명함삭제 3.명함수정 4.명함보기 5.종료:1
이름을 입력하세요 : 아이유
전화번호를 입력하세요 : 1234
1.명함추가 2.명함삭제 3.명함수정 4.명함보기 5.종료:1
이름을 입력하세요 : 박보검
전화번호를 입력하세요 : 3223
1.명함추가 2.명함삭제 3.명함수정 4.명함보기 5.종료:4
이름 전화번호
아이유 1234
박보검 3223
1.명함추가 2.명함삭제 3.명함수정 4.명함보기 5.종료:2
이름을 입력하세요 : 박보검
삭제되었습니다.
1.명함추가 2.명함삭제 3.명함수정 4.명함보기 5.종료:4
이름 전화번호
아이유 1234
1.명함추가 2.명함삭제 3.명함수정 4.명함보기 5.종료:2
이름을 입력하세요 : 웬디
이름을 잘못입력하셨습니다.
1.명함추가 2.명함삭제 3.명함수정 4.명함보기 5.종료:4
이름 전화번호
아이유 1234
1.명함추가 2.명함삭제 3.명함수정 4.명함보기 5.종료:3
이름을 입력하세요 : 아이유
수정하실 전화번호는 : 9876
수정되었습니다.
1.명함추가 2.명함삭제 3.명함수정 4.명함보기 5.종료:4
이름 전화번호
아이유 9876
1.명함추가 2.명함삭제 3.명함수정 4.명함보기 5.종료:3
이름을 입력하세요 : 슬기
이름을 잘못입력하셨습니다.
1.명함추가 2.명함삭제 3.명함수정 4.명함보기 5.종료:6
잘못입력하셨습니다.
1.명함추가 2.명함삭제 3.명함수정 4.명함보기 5.종료:5
프로그램을 종료합니다.
*/
1. ArrayList에서는 Enumeration을 못 쓴다. 대신 Iterator / for-each / for문을 사용한다.
- Enumeration은 JDK 1.0 시절의 구식 반복자
- JDK 1.2 이후 Iterator가 나와서 대부분의 컬렉션(ArrayList, HashSet, HashMap 등)에서는 Iterator/for-each가 표준이 됨
- 다만, 호환성 때문에 Vector, Hashtable 같은 오래된 클래스에는 elements() 메서드가 남아 있는 것
- ArrayList에는 elements() 메서드가 없다.
2. ArrayList에서 반복하는 방법
(1) Iterator
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
(2) 향상된 for문 (for-each)
for (String s : list) {
System.out.println(s);
}
(3) 일반 for문 (인덱스 이용)
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
- Vector, Hashtable → elements() 제공 → Enumeration 사용 가능
- ArrayList → elements() 없음 → Iterator / for-each 사용
'기초 및 언어 > ▶ Java&JSP' 카테고리의 다른 글
| 33. HashSet (0) | 2025.08.26 |
|---|---|
| 32. Vector와 Enumeration (1) | 2025.08.26 |
| 30. 컬렉션(Collection) (0) | 2025.08.24 |
| 29. Generic (1) | 2025.08.22 |
| 28. Calendar, Date, SimpleDataFormat (0) | 2025.08.22 |