컬렉션 프레임워크
자바는 널리 알려져 있는 자료구조를 바탕으로 객체들을 효율적으로 추가, 삭제, 검색할 수 있도록 관련된 인터페이스와 클래스들을 java.util 패키지에 포함시켜 놓았다. 이들을 총칭해서 컬렉션 프레임워크라고 부른다. 컬렉션 프레임워크는 몇 가지 인터페이스를 통해서 다양한 컬렉션 클래스를 이용할 수 있도록 설계되어 있다. 주요 인터페이스로는 List, Set, Map이 있는데, 이 인터페이스로 사용 가능한 컬렉션 종류는 다음과 같다.
| 인터페이스 분류 | 특징 | 구현 클래스 | |
| Collection | List | 순서를 유지하고 저장 중복 저장 가능 |
ArrayList, Vector, LinkedList |
| Set | 순서를 유지하지 않고 저장 중복 저장 안됨 |
HashSet, TreeSet | |
| Map | 키와 값으로 구성된 엔트리 저장 키는 중복 저장 안됨 |
HashMap, Hashtable, TreeMap, Properties | |
List 컬렉션
List 컬렉션은 객체를 인덱스로 관리하기 때문에 객체를 저장하면 인덱스가 부여되고 인덱스로 객체를 검색, 삭제할 수 있는 기능을 제공한다. List 컬렉션에는 ArrayList, Vector, LinkedList 등이 있는데, List 컬렉션에서 공통적으로 사용 가능한 List 인터페이스 메서드는 다음과 같다. 인덱스로 객체들이 관리되기 때문에 인덱스를 매개값으로 갖는 메서드들이 많다.
| 기능 | 메서드 | 설명 |
| 객체 추가 | boolean add(E e) | 주어진 객체를 맨 끝에 추가 |
| void add(int index, E element) | 주어진 인덱스에 객체를 추가 | |
| set(int index, E element) | 주어진 인덱스의 객체를 새로운 객체로 바꿈 | |
| 객체 검색 | boolean contains(Object o) | 주어진 객체가 저장되어 있는지 여부 |
| E get(int index) | 주어진 인덱스에 저장된 객체를 리턴 | |
| isEmpty() | 컬렉션이 비어 있는지 조사 | |
| int size() | 저장되어 있는 전체 객체 수를 리턴 | |
| 객체 삭제 | void clear() | 저장된 모든 객체를 삭제 |
| E remove(int index) | 주어진 인덱스에 저장된 객체를 삭제 | |
| boolean remove(Object o) | 주어진 객체를 삭제 |
ArrayList
ArrayList는 List 컬렉션에서 가장 많이 사용하는 컬렉션이다. ArrayListd에 객체를 추가하면 내부 배열에 객체가 저장된다. 일반 배열과의 차이점은 ArrayList는 제한 없이 객체를 추가할 수 있다는 것이다. List 컬렉션은 객체 자체를 저장하는 것이 아니라 객체의 번지를 저장한다. 또한 동일한 객체를 중복 저장할 수 있는데, 이 경우에는 동일한 번지가 저장된다. null 또한 저장이 가능하다.
List<E> list = new ArrayList<E>(); //E에 지정된 타입의 객체만 저장
List<E> list = new ArrayList<>((); //E에 지정된 타입의 객체만 저장, 객체 타입 생략
List list = new ArrayList(); //모든 타입의 객체를 저장
ArrayList 컬렉션에 객체를 추가하면 인덱스 0번부터 차례대로 저장된다. 특정 인덱스의 객체를 제거하면 바로 뒤 인덱스부터 마지막 인덱스까지 모두 앞으로 1씩 당겨진다. 마찬가지로 특정 인덱스에 객체를 삽입하면 해당 인덱스부터 마지막 인덱스까지 모두 1씩 밀려난다. 따라서 빈번한 객체 삭제와 삽입이 일어나는 곳에서는 ArrayList를 사용하는 것은 바람직하지 않다.
예제 코드
package ch15;
public class Board {
private String subject;
private String content;
private String writer;
public Board(String subject, String content, String writer) {
this.subject = subject;
this.content = content;
this.writer = writer;
}
public String getSubject() { return subject; }
public String getContent() { return content; }
public String getWriter() { return writer; }
public void setSubject(String subject) { this.subject = subject; }
public void setContent(String content) { this.content = content; }
public void setWriter(String writer) { this.writer = writer; }
}
package ch15;
import java.util.ArrayList;
import java.util.List;
public class ArrayListExample {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Board> list = new ArrayList<>();
list.add(new Board("제목", "내용1", "글쓴이1"));
list.add(new Board("제목", "내용2", "글쓴이2"));
list.add(new Board("제목", "내용3", "글쓴이3"));
list.add(new Board("제목", "내용4", "글쓴이4"));
list.add(new Board("제목", "내용5", "글쓴이5"));
int size = list.size();
System.out.println("총 객체 수: " + size);
System.out.println();
Board board = list.get(2);
System.out.println(board.getSubject() + "\t" + board.getContent() + "\t" + board.getWriter());
System.out.println();
for(int i=0; i<list.size(); i++) {
Board b = list.get(i);
System.out.println(b.getSubject() + "\t" + b.getContent() + "\t" + b.getWriter());
}
System.out.println();
list.remove(2);
list.remove(2);
for(Board b : list) {
System.out.println(b.getSubject() + "\t" + b.getContent() + "\t" + b.getWriter());
}
}
}
출력 결과
총 객체 수: 5
제목 내용3 글쓴이3
제목 내용1 글쓴이1
제목 내용2 글쓴이2
제목 내용3 글쓴이3
제목 내용4 글쓴이4
제목 내용5 글쓴이5
제목 내용1 글쓴이1
제목 내용2 글쓴이2
제목 내용5 글쓴이5
Vector
Vector는 ArrayList와 동일한 내부 구조를 가지고 있다. 차이점은 Vector는 동기화된 메서드로 구성되어 있기 때문에 멀티 스레드가 동시에 Vector() 메서드를 실행할 수가 없다는 것이다. 그렇기 때문에 멀티 스레드 환경에서는 안전하게 객체를 추가 또는 삭제할 수 있다.
List<E> list = new Vector<E>();
List<E> list = new Vector<>();
List list = new Vector();
예제 코드
package ch15;
import java.util.List;
import java.util.Vector;
public class VectorExample {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Board> list = new Vector<>();
Thread threadA = new Thread() {
@Override
public void run() {
for(int i=1; i<=1000; i++) {
list.add(new Board("제목" + i, "내용" + i, "글쓴이" + i));
}
}
};
Thread threadB = new Thread() {
@Override
public void run() {
for(int i=1; i<=1000; i++) {
list.add(new Board("제목" + i, "내용" + i, "글쓴이" + i));
}
}
};
threadA.start();
threadB.start();
try {
threadA.join();
threadB.join();
} catch(Exception e) {
}
int size = list.size();
System.out.println("총 객체 수: " + size);
System.out.println();
}
}
출력 결과
총 객체 수: 2000
LinkedList
LinkedList는 ArrayList와 사용 방법은 동일하지만 내부 구조는 완전히 다르다. ArrayList는 내부 배열에 객체를 저장하지만, LinkedList는 인접 객체를 체인처럼 연결해서 관리한다. LinkedList는 특정 위치에서 객체를 삽입하거나 삭제하면 바로 앞뒤 링크만 변경하면 되므로 빈번한 객체 삭제와 삽입이 일어나는 곳에서 좋은 성능을 발휘한다.
List<E> list = new LinkedList<E>();
List<E> list = new LinkedList<>();
List list = new LinkedList();
예제 코드
package ch15;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class LinkedExample {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> list1 = new ArrayList<String>();
List<String> list2 = new LinkedList<String>();
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.printf("%-17s %8d ns \n", "ArrayList 걸린 시간: ", + (endTime-startTime));
startTime = System.nanoTime();
for(int i=0; i<10000; i++) {
list2.add(0, String.valueOf(i));
}
endTime = System.nanoTime();
System.out.printf("%-17s %8d ns \n", "LinkedList 걸린 시간: ", + (endTime-startTime));
}
}
출력 결과
ArrayList 걸린 시간: 7109200 ns
LinkedList 걸린 시간: 1987100 ns'Language > JAVA' 카테고리의 다른 글
| [JAVA] Map 컬렉션 (0) | 2024.10.18 |
|---|---|
| [JAVA] Set 컬렉션 (0) | 2024.10.18 |
| [JAVA] 데몬 스레드와 스레드풀 (3) | 2024.10.17 |
| [JAVA] 스레드 메서드 (0) | 2024.10.17 |
| [JAVA] 멀티 스레드 (2) | 2024.10.17 |