자바는 널리 알려저 있는 자료구조를 사용해서 객체들을 효율적으로 추가, 삭제, 검색할 수있도록 인터페이스와 구현 클래스를 java.util 패키지에서 제공합니다. 이들을 총칭해서 컬렉션 프레임워크라고 부릅니다.
컬렉션은 검색,조회,정렬, 추가, 삭제와 같은 데이터를 관리할 수 있는 객체를 말하고, 프레임워크는 사용 방법을 정해놓은 라이브러리를 말합니다.
컬렉션 프레임워크는 인터페이스와 클래스로 나누어져 있습니다
인터페이스(interface)
-Set,List,Queue,Deque
클래스(class)
-ArrayList,Vector,LinkedList,Hastset,LinkedHashSet,TreeSet
컬렉션 프레임워크의 주요 인터페이스로는 List, Set, Map 이 있습니다.
배열과 비슷하게 객체를 인덱스로 관리합니다.
배열과의 차이점은 저장용량이 자동으로 증가하며,객체를 저장할떄 자동 인덱스가 부여된다는 것이다.그리고 추가,삭제,검색을 위한 다양한 메서드들이 제공된다.
-객체 추가
-객체 검색
-객체 삭제
List인터페이스의 대표적인 구현 클래스이다.
List<E> list = new ArrayList<E>();
-ArrayList를 생성하기 위해서는 저장할 객체 타입을 E타입 파라미터 자리에 표기하고 기본 생성자를 호출하면 된다. 예를 들어 String을 저장하는 ArrayList는 다음과 같이 생성이 가능하다.
List<String> list = new ArrayList<STring>();
따라서 빈번한 객체 삭제와 삽입이 일어나는 곳에서는 ArrayList를 사용하지않는 것이 바람직하지 않습니다.
package 컬렉션프레임워크;
import java.util.*;
public class ArrayListExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
//String 객체를 저장
list.add("Java");
list.add("JDBC");
list.add("Servlet/JSP");
list.add(2, "Database");
list.add("iBATIS");
//저장된 총 객체수 얻기
int size = list.size();
System.out.println("총 객체수: " + size);
System.out.println();
//2번인덱스의 객체 얻기
String skill = list.get(2);
System.out.println("2: " + skill);
System.out.println();
//저장된 총 객체 수만 큼 루핑
for (int i = 0; i < list.size(); i++) {
String str = list.get(i);
System.out.println(i + ":" + str);
}
System.out.println();
list.remove(2); //2접ㄴ 인덱스 객체 삭제됨
list.remove(2);
list.remove("iBATIS");
for (int i = 0; i < list.size(); i++) {
String str = list.get(i);
System.out.println(i + ":" + str);
}
}
}
Vector은 ArrayList와 동일한 내부 구조를 가지고 있습니다.Vector를 생성하기 위해서는 저장할 객체 타입을 타입 파라미터로 표기하고 기본 생성자를 호출하면 된다.
package 컬렉션프레임워크;
public class Board {
public String subject;
public String content;
public String writer;
public Board(String subject, String content, String writer) {
this.subject = subject;
this.content = content;
this.writer = writer;
}
}
package 컬렉션프레임워크;
import java.util.*;
public class VectorExample {
public static void main(String[] args) {
List<Board>list = new Vector<>();
list.add(new Board("제목1","제목1","글쓴이1"));
list.add(new Board("제목2","제목2","글쓴이2"));
list.add(new Board("제목3","제목3","글쓴이3"));
list.add(new Board("제목4","제목4","글쓴이4"));
list.add(new Board("제목5","제목5","글쓴이5"));
list.remove(2);// 2번 인덱스 객체(제목3)삭제(뒤의 인덱스는 1씩 앞으로 당겨짐)
list.remove(3);// 3번 인덱스 객체(제목5)삭제
for(int i=0; i<list.size(); i++){
Board board =list.get(i);
System.out.println(board.subject +"\t"+board.content+"\t"+board.writer);
}
}
}
만약 ArrayList의 remove였다고한다면
list.remove(2)에서 제목3 이 삭제되고
list.remove(3)에서 제목4가 삭제 되었다.
LInkedList는 List구현 클래스이므로 ArrayList와 사용 방법은 똑같지만, 내부구조는 완전히 다릅니다. ArrayList는 내부 배열에 객체를 저장해서 관리하지만, LinkedList는 인접 참조를 링크해서 체인처럼 관리합니다.
다음 예제는 ArrayList와 LinkedList에 10,000개의 객체를 삽입하는데 걸린 시간을 측정한 것입니다.
0번 인덱스에 String객체를 10,000번 추가하기 위해 List 인터페이스의 add(int index,E element) 메서드를 사용했습니다.
package 컬렉션프레임워크;
import java.util.ArrayList;
import java.util.*;
public class LinkedListExample {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
List<String> list2 = new LinkedList<>();
long startTime;
long endTime;
startTime=System.nanoTime();
for(int i=0; i<10000; i++){
list1.add(0,String.valueOf(i));
}
endTime=System.nanoTime();
System.out.println("ArrayList 걸린시간: "+(endTime-startTime)+" ns");
startTime = System.nanoTime();
for(int i=0; i<10000; i++){
list2.add(0,String.valueOf(i));
}
endTime=System.nanoTime();
System.out.println("LinkedList 걸린시간: "+(endTime-startTime)+" ns");
}
}
실행결과를 보면 LinkedList가 훨씬 빠른 성능을 발휘합니다.
끝에서부터(순차적으로) 추가 또는 삭제하는 경우에는 ArrayList가 빠르지만, 중간에 추가, 삭제하는 경우에는 앞뒤 링크 정보만 변경하므로 LinkedList가 더 빠릅니다.
ArrayList는 뒤쪾 인덱스들을 모두 1씩 증가 또는 감소시키는 시간이 필요하므로 처리 속도가 느립니다.
구분 | 순차적으로 추가/삭제 | 중간에 추가/삭제 | 검색 |
---|---|---|---|
ArrayList | 빠르다 | 느리다 | 빠르다 |
LinkedList | 느리다 | 빠르다 | 느리다 |