ArrayList란 기존의 배열을 개선한 것으로, collection framework에서 가장 많이 사용되는 자료구조이다.
ArrayList
는 기존의 배열에서 불편한 부분을 개선한 것으로, 배열의 특징과 리스트의 특징을 전부 갖고 있다. 따라서, 사용할때는 배열을 사용하는 방식과 비슷하게 사용할 수 있다.
ArrayList
의 특징은 다음과 같다.
연속적인 데이터 리스트
데이터가 배열에 순차적으로 들어가듯 ArrayList
에서는 데이터가 빈 공간 없이 순차적으로 저장이 된다.
Object
클래스를 이용해 데이터 저장
ArrayList
내부에서는 Object[]
배열을 이용해 데이터를 저장하기 때문에 숫자, 문자, 문자열 뿐 아니라 클래스 역시 저장할 수 있다.
배열을 이용하기에 요소에 빠르게 접근 가능
ArrayList
는 결국 배열을 이용하기 때문에 배열의 장점인 빠른 인덱스의 접근이 가능하다.
배열이 가득 찼을 경우 자동으로 배열의 길이를 늘림
ArrayList
는 배열을 기반으로 제작되기 때문에 배열의 단점인 크기의 한계가 있다. 이때, ArrayList
에서는 내부의 배열이 가득 찼을 경우 더 큰 크기의 배열을 생성해 기존의 가득 찬 배열의 값을 더 큰 배열에 복사하는 방식으로 동작하기 때문에 이 과정에서 지연시간이 발생한다.
배열의 중간에 삽입/삭제시 동작이 느림
중간에 빈 공간을 없게 하는 것을 원칙으로 하기 때문에 인덱스의 중간에 데이터를 삽입/삭제를 하면 모든 요소들의 위치를 이동해야 하기 때문에 삽입/삭제 동작이 느리다.
ArrayList
자체자 배열을 이용해 만들었기 때문에 배열과 ArrayList
는 서로 비슷할 수 밖에 없다.
그럼에도 이 둘 사이의 차이점이 있다.
이 둘의 가장 큰 차이점은 크기가 고정되 있는가(resizable)에 있다.
원칙적으로, 배열의 경우 크기가 고정되 있어 변경이 불가능하다. 그러나, ArrayList
는 속도가 느리긴 하더라도 크기를 동적으로 늘릴 수 있다.
또한, ArrayList
는 추후에 배울 iterator
라는 것을 이용해 각 요소들을 순회할 수 있으나, 일반적인 배열은 이 iterator
라는 것을 사용할 수 없다. 즉, 배열의 값을 순회하기 위해서는 반복문을 사용해야 한다는 차이점 역시 있다.
또한 ArrayList
는 추후에 배울 제네릭을 사용할 수 있으며, Object
형태로만 저장이 가능하다.
즉, 일반적인 int
, double
과 같은 원시 자료형은 저장이 불가능해 wrapper class를 이용하거나 제네릭을 이용해 저장을 해야 하는 반면, 배열은 원시 자료형 역시 저장할 수 있다.
ArrayList
를 사용하기 위해서는 java.util.ArrayList
패키지를 import 해야 한다.
주로 사용되는 메소드는 다음과 같다.
boolean add(Object o)
마지막 인덱스에 객체 o를 저장한다.
void add(int index, Object o)
주어진 위치(index)에 객체 o를 저장한다.
boolean addAll(Collection c)
컬렉션에 있는 모든 객체를 저장한다.
void clear()
ArrayList
의 모든 요소를 숙청 삭제 한다.
Object clone()
ArrayList
객체를 복사한다.
boolean contains(Object o)
해당 객체가 리스트에 포함되 있는지 확인한다.
void ensureCapacity(int minCapacity)
리스트의 용량을 최소한 minCapacity 크기로 조절한다.(용량을 늘릴때 주로 사용)
Object get(int index)
해당 index에 있는 객체를 반환한다.
int indexOf(Object o)
해당 객체가 있는 위치를 반환한다.
boolean isEmpty()
Iterator iterator()
int lastIndexOf(Object o)
ListIterator listIterator()
ListIterator를 반환한다.
ListIterator listIterator(int index)
index부터 시작하는 ListIterator를 반환한다.
boolean remove(Object o)
해당 객체를 방사능 홍차로 제거한다.
boolean remove(int index)
해당 위치에 있는 객체를 죽★창으로 제거한다.
boolean removeAll(Collection c)
ArrayList
를 생성해서 기본적인 입출력은 다음과 같이 할 수 있다.
import java.util.ArrayList;
public class Main {
public static void main(String[] args){
ArrayList list = new ArrayList();
/*리스트에 추가하는 연산*/
list.add("String");
list.add("스트링 치즈");
list.add("먹고싶다.");
list.add("cheese");
list.add("is");
list.add("truth.");
list.add("치즈는");
list.add("진리다.");
System.out.println("---list print---");
System.out.println(list);
list.remove("String");
System.out.println(" \"String\" is deleted.");
System.out.println("---list print---");
System.out.println(list);
list.remove(0);
System.out.println(" 0 index is deleted");
System.out.println("---list print---");
System.out.println(list);
list.remove(0);
System.out.println(" 0 index is deleted");
System.out.println("---list print---");
System.out.println(list);
}
}
output
---list print---
[String, 스트링 치즈, 먹고싶다., cheese, is, truth., 치즈는, 진리다.]
"String" is deleted.
---list print---
[스트링 치즈, 먹고싶다., cheese, is, truth., 치즈는, 진리다.]
0 index is deleted
---list print---
[먹고싶다., cheese, is, truth., 치즈는, 진리다.]
0 index is deleted
---list print---
[cheese, is, truth., 치즈는, 진리다.]
치즈에 미쳐있는 필자가 보일 것이다.
그러나, 현실에서는 제네릭을 같이 활용해서 다음과 같이 작성하곤 한다.
import java.util.ArrayList;
public class Main {
public static void main(String[] args){
ArrayList<String> list = new ArrayList();// <>제네릭 사용.
/*리스트에 추가하는 연산*/
list.add("String");
list.add("스트링 치즈");
list.add("먹고싶다.");
list.add("cheese");
list.add("is");
list.add("truth.");
list.add("치즈는");
list.add("진리다.");
System.out.println("---list print---");
System.out.println(list);
list.remove("String");
System.out.println(" \"String\" is deleted.");
System.out.println("---list print---");
System.out.println(list);
list.remove(0);
System.out.println(" 0 index is deleted");
System.out.println("---list print---");
System.out.println(list);
list.remove(0);
System.out.println(" 0 index is deleted");
System.out.println("---list print---");
System.out.println(list);
}
}
제네릭은 아직 안배웠으니 나중에 자세히 다루도록 하며, 일단 리스트같은 자료구조는 대부분 제네릭과 같이 사용한다라고 알아두자.
ArrayList
에서 특정 객체를 검색하는 것은 .contains()
과 .indexof()
메소드를 사용한다.
import java.util.ArrayList;
public class Main {
public static void main(String[] args){
ArrayList<String> list = new ArrayList();
int idx;
/*리스트에 추가하는 연산*/
list.add("String");
list.add("스트링 치즈");
list.add("먹고싶다.");
list.add("cheese");
list.add("is");
list.add("truth.");
list.add("치즈는");
list.add("진리다.");
System.out.println("---list print---");
System.out.println(list);
/*"스트링 치즈" 객체 삭제*/
if(list.contains("스트링 치즈")){
idx=list.indexOf("스트링 치즈");
list.remove(idx);
}
System.out.println("---list print---");
System.out.println(list);
}
}
ArrayList
를 이용해 도서 관리 시스템을 만들어 보자.
도서관리 시스템에서는 다음과 같은 메뉴가 있다.
1. 책 추가
2. 책 삭제
3. 책 검색
4. 책 목록 출력
5. 종료
책은 오직 책 이름으로 추가/삭제/검색이 가능하며, 종료 버튼(5)를 눌러야 프로그램이 종료된다.
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args){
ArrayList<String> bookList = new ArrayList();
Scanner sc = new Scanner(System.in);
int menu;
String book_name;
do{
System.out.println("\n\n---------메뉴---------");
System.out.println("1. 책 추가.");
System.out.println("2. 책 삭제.");
System.out.println("3. 책 검색.");
System.out.println("4. 책 목록 출력.");
System.out.println("5. 종료.");
menu = Integer.parseInt(sc.nextLine());
switch(menu){
case 1:
System.out.print("추가할 책 이름: ");
book_name= sc.nextLine();
bookList.add(book_name);// 책 추가
System.out.println("책이 추가됬습니다.");
break;
case 2:
System.out.print("삭제할 책 이름: ");
book_name= sc.nextLine();
if(bookList.contains(book_name) ){
bookList.remove(book_name);
System.out.println("책이 삭제됬습니다.");
}
else{
System.out.println("책이름이 잘못됬습니다.");
}
break;
case 3:
System.out.print("검색할 책 이름: ");
book_name= sc.nextLine();
if(bookList.contains(book_name) ){
int index;
index=bookList.indexOf(book_name);
System.out.println("책이 "+index+" 번째에 있습니다.");
}
else{
System.out.println("해당 이름의 책이 없습니다..");
}
break;
case 4:
int i=1;
for(String name : bookList){
System.out.println(i+". "+name);
i++;
}
break;
case 5:
break;
default:
System.out.println("해당 메뉴는 존재하지 않습니다.");
}
} while(menu!=5);
}
}