본 내용은 <자바의 정석> 내용을 복습, 정리하였습니다.
Chapter 11. 컬렉션 프레임워크
1. 컬렉션 프레임워크
(1) 컬렉션 프레임워크의 핵심 인터페이스
- 컬렉션 프레임워크 : 데이터 군을 저장하는 클래스들을 표준화한 설계
- JDK1.2 이전까지는 Vector, Hashtable, Properties와 같은 컬렉션 클래스, 다수의 데이터를 저장할 수 있는 클래스들을 서로 다른 각자의 방식으로 처리
- JDK1.2 이후부터 다양한 종류의 컬렉션 클래스가 추가되고 모든 컬렉션 클래스를 표준화된 방식으로 다룰 수 있도록 체계화
- 컬렉션 프레임워크의 핵심 인터페이스
- List, Set, Map
- 이 중 List, Set의 공통 부분을 뽑아 새로운 인터페이스인 Collection을 추가
- Map의 경우 List, Set과는 다른 형태로 컬렉션을 다루기 때문에 상속 계층도에 포함되지 못함
- 추후 컬렉션 프레임워크의 실제 소스를 분석해보면 객체지향적 설계 능력을 향상시키는데 많은 도움이 될 것
- 컬렉션 프레임워크 핵심 인터페이스의 특징
- List : 순서가 있는 데이터의 집합, 데이터 중복 허용
- ArrayList, LinkedList, Stack, Vector 등
- Set : 순서를 유지하지 않는 데이터의 집합, 데이터 중복 허용하지 않음
- Map : 키와 값의 쌍으로 이루어진 데이터의 집합, 순서는 유지되지 않고 키는 중복을 허용하지 않으며 값은 중복 허용
- HashMap, Treemap, Hashtable, Properties
- Collection 인터페이스의 주요 메서드
- 지정된 객체나 컬렉션의 객체들을 컬렉션에 추가
boolean add(Object o)
boolean addAll(Collection c)
- 컬렉션의 모든 객체들을 삭제
void clear()
- 지정된 객체나 컬렉션의 객체들이 컬렉션에 포함되어 있는지 확인
boolean contains(Object o)
boolean containsAll(Collection c)
- 컬렉션이 비어있는지 확인
boolean isEmpty()
- 컬렉션의 이터레이터를 얻어서 반환
Iterator iterator
- 지정된 객체를 삭제
boolean remove(Object o)
- 지정된 컬렉션에 포함된 객체들을 삭제
boolean removeAll(Object o)
- 지정된 컬렉션에 포함된 객체만을 남기고 다른 객체들은 컬렉션에서 삭제, 해당 작업으로 컬렉션에 변화가 있으면 true를, 그렇지 않으면 false를 반환
boolean retainAll(Collection c)
- 컬렉션에 저장된 객체의 개수 반환
int size()
- 컬렉션에 저장된 객체를 객체 배열로 반환
Object[] toArray()
- 지정된 배열에 컬렉션의 객체를 저장해서 반환
Object[] toArray(Object[] a)
- List 인터페이스의 주요 메서드
- 지정된 위치에 객체 또는 컬렉션에 포함된 객체들을 추가
void add(int index, Object element)
boolean addAll(int index, Collection c)
- 지정된 위치에 있는 객체를 반환
Object get(int index)
- 지정된 객체의 위치를 반환(정방향)
int indexOf(Object o)
- 지정된 객체의 위치를 반환(역방향)
int lastIndexOf(Object o)
- 리스트 객체에 접근할 수 있는 리스트 이터레이터 반환
ListIterator listIterator()
ListIterator listIterator(int index)
- 지정된 위치에 있는 객체를 삭제하고 삭제된 객체를 반환
Object remove(int index)
- 지정된 위치에 객체를 저장
Object set(int index, Object element)
- 지정된 비교자로 리스트를 정렬
void sort(Comparator c)
- 지정된 범위에 있는 객체를 반환
List subList(int fromIndex, int toIndex)
- Set 인터페이스
- Set 인터페이스를 구현한 클래스로는 HashSet, TreeSet이 있음
- Map 인터페이스의 주요 메서드
- 맵의 모든 객체를 삭제
void clear()
- 지정된 키 객체와 일치하는 맵의 키 객체가 있는지 확인
boolean containsKey(Object key)
- 지정된 값 객체와 일치하는 맵의 값 객체가 있는지 확인
boolean containsValue(Object value)
- 맵에 저장되어 있는 키-값 쌍을 Map.Entry 타입의 객체를 저장한 Set으로 반환
Set entrySet()
- 맵이 비어 있는지 확인
boolean isEmpty()
- 맵에 저장된 모든 키 객체를 반환
Set keySet()
- 맵에 있는 모든 값 객체를 키 객체에 연결하여 저장
Object put(Object key, Object value)
- 지정된 맵의 모든 키-값 쌍을 추가한다
void putAll(Map t)
- 지정된 키 객체와 일치하는 모든 키-값 객체를 삭제
Object remove(Object key)
- 맵에 저장된 키-값 쌍의 개수를 반환
int size()
- 맵에 저장된 모든 값 객체를 반환
Collection values()
(2) ArrayList
- 컬렉션 프레임워크에서 가장 많이 사용되는 컬렉션 클래스
- List 인터페이스를 구현하므로 데이터의 저장 순서가 유지되고 중복을 허용
- Object 배열을 이용하여 데이터를 순차적으로 저장
- 기본적으로 배열(array)와 동일하게 크기는 10이며, 배열에 더 이상 저장할 공간이 없으면 보다 큰 새로운 배열을 생성하여 기존의 배열에 저장된 내용을 새로운 배열로 복사한 다음에 저장됨
- 요소가 삭제될 때마다 빈 공간을 채우기 위해 나머지 요소들이 자리 이동을 한다는 특징이 있음
(3) LinkedList
- 배열은 가장 간단한 구조와 데이러를 읽어오는데 걸리는 시간이 가장 빠르지만 아래와 같은 단점이 있음
- 크기를 변경할 수 없음 -> 따라서 새로운 배열을 생성해서 데이터를 복사해야 함
- 비순차적인 데이터의 추가 또는 삭제에 시간이 많이 걸림
- 링크드 리스트 : 불연속적으로 존재하는 데이터를 서로 연결한 형태로 구성, 각 요소(node) 들은 자신과 연결된 다음 요소에 대한 참조(주소값)와 데이터로 구성
- 더블 링크드 리스트 : 이중 연결 리스트, 참조 변수를 하나 더 추가하여 다음 요소 뿐만 아니라 이전 요소에 대한 참조가 가능
- 실제로 LinkedList 클래스는 더블 링크드 리스트로 구현되어 있음
- ArrayList와의 비교
- 순차적인 추가 / 삭제에 대해서는 ArrayList가 빠름
- 다만, ArrayList의 크기가 충분하지 않을 경우 새로운 데이터를 추가할 때마다 배열을 복사해야 해서 LinkedList가 더 빠를 수도 있음
- 중간 데이터를 추가/삭제하는 경우 LinkedList가 빠름
- LinkedList의 경우 각 요소 간의 연결만 변경하면 되지만 ArrayList는 각 요소들을 재배치해야 하므로 처리 속도가 느림
(4) Stack, Queue
- 스택은 ArrayList와 같은 배열 기반의 컬렉션 클래스가 적합
- 스택은 Stack 클래스로 구현하여 제공하고 있음
Object peek()
: Stack의 맨 위에 저장된 객체를 반환, pop()
과 달리 Stack 에서 객체를 꺼내지는 않음 (비었을 시 EmptyStackException 발생)
Object pop()
: Stack의 맨 위에 저장된 객체를 꺼냄 (비었을 시 EmptyStackException 발생)
Object push(Object item)
: Stack에 객체를 저장
int search(Object o)
: Stack에 주어진 객체를 찾아 그 위치를 반환, 못 찾을 경우 -1을 반환
- 큐의 경우 데이터를 꺼낼 때마다 빈공간을 채워야 하므로 데이터의 추가/삭제가 쉬운 LinkedList로 구현하는 것이 적합
- 큐의 경우 Queue 인터페이스로만 정의했을 뿐 별도의 클래스를 제공하고 있지는 않음. 다만, Queue 인터페이스를 구현한 클래스들이 있음
boolean add(Object o)
: 지정된 객체를 Queue에 반환, 저장 공간 부족 시 IllegalStateException 반환
Object remove()
: Queue에서 객체를 꺼내 반환, 비어있을 시 NoSuchElementException 반환
Object element()
: 삭제 없이 요소를 읽어옴, peek과 달리 비어 있을 시 NoSuchElementException 반환
boolean offer(Object o)
: Queue에 객체를 저장, 성공하면 true, 실패 시 false 반환
Object poll()
: Queue에서 객체를 꺼내 반환, 비어 있으면 null 반환
Object peek()
: 삭제 없이 요소를 읽어오며 비어 있으면 null 반환
- PriorityQueue : Queue 인터페이스의 구현체 중 하나, 저장한 순서에 관계 없이 우선순위가 높은 것부터 꺼내며 null을 저장할 수 없음
- 저장 공간으로 배열을 사용, 각 요소를 힙이라는 자료구조의 형태로 저장
(5) Iterator, ListIterator, Enumeration
- 모두 컬렉션에 저장된 요소를 접근하는데에 사용되는 인터페이스
- Enumeration은 Iterator의 구버전, ListIterator는 Iterator의 기능 향상 버전
- Iterator
- 컬렉션 프레임워크에서 컬렉션에 저장된 요소들을 읽어오는 방법을 표준화
- Iterator 인터페이스를 정의하고 컬렉션 인터페이스에는 Iterartor를 반환하는 iterator()를 정의
boolean hasNext()
: 읽어올 요소가 남아 있는지 확인
Object next()
: 다음 요소를 읽음, hasNext()로 먼저 체크하는 것이 안전
void remove()
: next()로 읽어 온 요소를 삭제
- Map의 경우 키-값 쌍으로 저장을 하고 있어 iterator를 직접 호출할 수는 없고 keySet()이나 entrySet()과 같은 메서드로 키와 값을 따로 Set의 형태로 얻어온 후 iterator()를 호출해야 함
- ListIterator : Iterator에 양방향 조회 기능 추가(List 구현 시에만 사용 가능)