[JAVA 기초] Collection Framework
Intro
Collection 이란 말대로 데이터의 그룹 집합체라는 의미를 뜻하며, 이 데이터의 그룹을 어느 상황에 사용되어야 하며, 언제 유리한지를 알아야, 보다 좋은 프로그램을 만들 수 있기 때문에 이에 대한 내용을 정리해보았습니다.
또한 이에 해당하는 시간 복잡도와 성능은 추후에 정리 예정입니다.
Collection Framework
다수의 데이터를 쉽고 효과적으로 처리할 수 있는 표준화된 방법(자료구조)을 제공하는 클래스와 이를 정의하는 인터페이스를 제공
1. Collection을 사용하는 이유
- 일관된 API: Collection 밑에 있는 모든 클래스, 인터페이스는 이를 상속받아 통일된 메서드를 사용
- 프로그래밍 비용 감소: 객체 지향 프로그래밍의 추상화의 기본 개념이 구현되어 있음
- 프로그램 속도 및 품질 향상: 데이터의 구조와 알고리즘은 속도와 성능 향상에 큰 영향을 끼침
- Collection을 이용해 최상의 구현을 간단하게 구현 가능
2. Collection Framwork 상속 구조
![]() |
3. Collection Interface
(1) 특징
Iterator 인터페이스를 상속한 Collection은 가장 기본이 되는 인터페이스로 add(), size(), iterator() 메소드를 가지고 있음.
(2) 주요 메소드
메소드 | 설명 |
boolean add(E e) | 해당 컬렉션에 전달된 요소를 추가함. |
void clear() | 해당 컬렉션에 모든 요소를 제거함. |
boolean contains(Object o) | 해당 컬렉션이 전달된 객체를 포함하고 있는 지를 확인 |
boolean equals(Object o ) | 해당 컬렉션과 전달된 객체가 같은지를 확인 |
boolean isEmpty() | 해당 컬렉션이 비어있는 지를 확인 |
Iterator<E>iterator() | 해당 컬렉션의 반복자를 반환 |
boolean remove(Object o) | 해당 컬렉션의 전달된 객체를 제거 |
int size() | 해당 컬렉션의 요소의 총 개수를 반환 |
Object[] toArray() | 해당 컬렉션의 모든 요소를 Object 타입의 배열로 반환 |
4. Collections
(1) 특징
Collection 인터페이스와 달리 Java 1.2 이상부터 Collections라는 static클래스가 존재
(2) 주요 메소드
메소드 | 설명 |
Collections.sort(List L) | 리스트를 정렬 |
Collectinos.sort(List L, reverseOrder()) | 리스트를 역순으로 정렬 |
max(List L), min(List L) | 리스트에서 최대, 최솟값 |
shuffle(List L) | 리스트를 랜덤으로 섞음 |
binarySearch(List L , Key) | 오름차순으로 정렬된 리스트에서 이진검색을 통해 위치를 반환, 실패시 -1반환 |
disjoint(List L1 , List L2) | 두 리스트 값이 완전히 다른지 검사, 하나라도 같은 값이 있으면 False |
(3) 예시 코드
![]() |
[출력]
![]() |
5. 주요 인터페이스 간략한 특징 및 자료 구조 별 특징
인터페이스 | 설명 | 구현 클래스 |
List<E> | 순서가 있는 데이터의 집합, 데이터의 중복을 허용 | Vector, ArrayList, LinkedList, Stack, Queue |
Set<E> | 순서가 없는 데이터의 집합, 데이터의 중복을 허용하지 않음 | HashSet, TreeSet |
Map<K,V> | 키와 값의 한 쌍으로 이루어지는 데이터의 집합으로, 순서가 없음 키는 중복을 허용하지 않지만, 값은 중복될 수 있음 |
HashMap,TreeMap,Hashtable,Properties |
※ 컬렉션 프레임워크를 구성하는 모든 클래스는 제네릭으로 표현됨
(1) 자료 구조 별 특징
![]() |
※ Thread-safe는 멀티 스레드 프로그래밍에서 일반적으로 어떤 함수나 변수, 혹은 객체가 여러 스레드로부터 동시에 접근이 이루어져도 프로그램의 실행에 문제가 없음을 뜻한다. 보다 엄밀하게는 하나의 함수가 한 스레드로부터 호출되어 실행 중일 때, 다른 스레드가 그 함수를 호출하여 동시에 함께 실행되더라도 각 스레드에서의 함수의 수행 결과가 올바로 나오는 것으로 정의
6. List 인터페이스
- index라는, 데이터의 중복을 허용하는 자료구조
- 객체의 자체를 저장하는 것이 아닌 객체의 메모리 번지를 참조, null 은 객체를 참조하지 않음
(1) 주요 메소드
메소드 | 설명 |
boolean add(E e) | 해당 리스트(list)에 전달된 요소를 추가함. (선택적 기능) |
void add(int index, E e) | 해당 리스트의 특정 위치에 전달된 요소를 추가함. (선택적 기능) |
void clear() | 해당 리스트의 모든 요소를 제거함. (선택적 기능) |
boolean contains(Object o) | 해당 리스트가 전달된 객체를 포함하고 있는지를 확인함. |
boolean equals(Object o) | 해당 리스트와 전달된 객체가 같은지를 확인함. |
E get(int index) | 해당 리스트의 특정 위치에 존재하는 요소를 반환함. |
boolean isEmpty() | 해당 리스트가 비어있는지를 확인함. |
Iterator<E> iterator() | 해당 리스트의 반복자(iterator)를 반환함. |
boolean remove(Object o) | 해당 리스트에서 전달된 객체를 제거함. (선택적 기능) |
boolean remove(int index) | 해당 리스트의 특정 위치에 존재하는 요소를 제거함. (선택적 기능) |
E set(int index, E e) | 해당 리스트의 특정 위치에 존재하는 요소를 전달받은 객체로 대체함. (선택적 기능) |
int size() | 해당 리스트의 요소의 총 개수를 반환함. |
Object[] toArray() | 해당 리스트의 모든 요소를 Object 타입의 배열로 반환함. |
7. List 대표적 구현 클래스
(1) ArrayList <E> 클래스
[특징]
- 단 방향 포인터 구조로 각 데이터에 대한 인덱스를 가지고 있어 조회 기능에 성능이 뛰어남
- 배열과 달리 초기 크기를 지정하지 않아도 되므로, 삽입 삭제가 자유로움
[단점]
- ArrayList 클래스는 배열을 이용하기 때문에, 크기를 늘릴 때 새로울 배열을 생성하고, 기존의 요소들을 옮겨야 하는 복잡한 과정을 거침, 물론 이 과정이 자동으로 수행되지만, 요소의 추가 및 삭제 작업에 걸리는 시간이 매우 길어짐
[예시 코드]
![]() |
[출력]
![]() |
(2) LinkedList <E> 클래스
[특징]
- ArrayList 클래스가 배열을 이용하여 요소를 저장함으로써 발생하는 단점을 극복하기 위해 고안
- jdk 1.2부터 제공된 LinkedList 클래스 내부적으로 이중 연결 리스트를 이용하여 요소 저장
- 저장된 요소는 비순차적으로 분포, 이러한 요소 사이를 링크로 연결하여 구성
- 양방향 포인터 구조로 데이터의 삽입, 삭제가 빈번할 경우 데이터의 위치정보만 수정하면 되기에 유용
- 스택, 큐, 양방향 큐 등을 만들기 위한 용도로 쓰임
[예시 코드]
![]() |
[출력]
![]() |
(3) Vector<E> 클래스
[특징]
- 과거에 대용량 처리를 위해 사용했으며, 내부에서 자동으로 동기화 처리가 일어나 비교적 성능이 좋지 않고 무거워 잘 쓰이지 않음, 현재는 사용은 가능하나 호환성을 위해서만 남아, 사용하지 않는 것을 권장
8. Set 인터페이스
- 순서가 없고, 데이터 유일성을 가지는 자료구조
- 순서가 없음으로 인덱스로 객체를 가져오는 get 메소드가 존재 하지 않음, 하진만 Iterator 제공
(1) 주요 메소드
메소드 | 설명 |
boolean add(E e) | 주어진 객체를 저장 후 성공적이면 true를 중복 객체면 false를 리턴합니다. |
boolean contains(Object o) | 주어진 객체가 저장되어있는지 여부를 리턴합니다. |
Iterator<E> iterator() | 저장된 객체를 한번씩 가져오는 반복자를 리턴합니다. |
isEmpty() | 컬렉션이 비어있는지 조사합니다. |
int Size() | 저장되어 있는 전체 객체수를 리턴합니다. |
void clear() | 저장된 모든 객체를 삭제합니다. |
boolean remove(Object o) | 주어진 객체를 삭제합니다. |
9. Set 구현 클래스
(1) HashSet <E> 클래스
[특징]
- 해시 알고리즘을 사용해 검색 속도가 빠름
- 순서를 예측할 수 없음
- 내부적으로 HashMap 인스턴스를 이용하여 요소를 저장
※ 요소의 저장 순서를 유지해야 한다면 jdk 1.4부터 제공하는 LinkedHashSet 클래스 사용
[예시 코드]
![]() |
[출력]
![]() |
※ 출력 결과를 통해 중복 데이터가 저장이 되지 않음을 확인할 수 있다.
(2) TreeSet <E> 클래스
[특징]
- 데이터가 정렬된 상태로 저장되는 이진 검색 트리의 형태로 요소를 저장
- 이진 검색 트리는 데이터를 추가, 제거 등 기본 동작 시간이 매우 빠릅니다.
- TreeSet 클래스는 NavigableSet 인터페이스를 기존의 이진 검색 트리 성능을 향상한 레드-블랙 트리로 구현됨
- Set 인터페이스를 구현하므로, 요소를 순서에 상관없이 저장하고 중복된 값은 저장하지 않음
[예시 코드]
![]() |
[출력]
![]() |
※ 데이터가 정렬된 상태(이진 검색 트리 형태)로 저장됨으로 오른 차순으로 정렬되어 출력
10. Map 인터페이스
- Map 인터페이스는 Collection 인터페이스와는 다른 저장 방식을 가짐
- Map 인터페이스를 구현한 Map 컬렉션 클래스들은 키와 값을 하나의 쌍으로 저장하는 방식 (key-value 방식)
- 요소의 저장 순서를 유지하지 않음
- 키는 중복을 허용하지 않지만, 값의 중복은 허용(중복된 키 값이 들어오면 기존의 값은 사라지고 새로운 값으로 대체)
(1) 주요 메소드
메소드 | 설명 |
V put(K Key, V value) | 주어진 키와 값을 추가하여 저장되면 값을 리턴합니다. |
boolean containsKey(Object Key) | 주어진 키가 있는지 확인합니다. |
boolean containsValue(Object value) | 주어진 값이 있는지 확인합니다. |
Set<Map.Entry<K,V>> entrySet() | 모든 Map.Entry 객체를 Set에 담아 리턴합니다. |
Set<K> keySet() | 모든 키를 Set객체에 담아서 리턴합니다. |
V get(Object key) | 주어진 키에 있는 값을 리턴합니다. |
boolean isEmpty() | 컬렉션이 비어있는지 조사합니다. |
int Size() | 저장되어 있는 전체 객체의 수를 리턴합니다. |
Collection<V> values() | 저장된 모든 값을 Collection에 담아서 리턴합니다. |
void clear() | 저장된 모든 Map.Entry를 삭제합니다. |
V remove(Object Key) | 주어진 키와 일치하는 Map.Entry를 삭제하고 값을 리턴합니다. |
(2) 주요 메소드 예시 코드
![]() |
![]() |
[출력]
![]() |
11. Map 구현 클래스
(1) HashMap <K, V> 클래스
[특징]
- 해시 알고리즘을 사용하여 검색 속도가 빠름
- 중복된 키로는 값을 저장할 수 없음, 하지만 같은 값을 다른 키로 저장하는 것은 가능
[주요 메소드]
메소드 | 설명 |
void clear() | 해당 맵(map)의 모든 매핑(mapping)을 제거함. |
boolean containsKey(Object key) | 해당 맵이 전달된 키를 포함하고 있는지를 확인함. |
boolean containsValue(Object value) | 해당 맵이 전달된 값에 해당하는 하나 이상의 키를 포함하고 있는지를 확인함. |
V get(Object key) | 해당 맵에서 전달된 키에 대응하는 값을 반환함. 만약 해당 맵이 전달된 키를 포함한 매핑을 포함하고 있지 않으면 null을 반환함. |
boolean isEmpty() | 해당 맵이 비어있는지를 확인함. |
Set<K> keySet() | 해당 맵에 포함되어 있는 모든 키로 만들어진 Set 객체를 반환함. |
V put(K key, V value) | 해당 맵에 전달된 키에 대응하는 값으로 특정 값을 매핑함. |
V remove(Object key) | 해당 맵에서 전달된 키에 대응하는 매핑을 제거함. |
boolean remove(Object key, Object value) | 해당 맵에서 특정 값에 대응하는 특정 키의 매핑을 제거함. |
V replace(K key, V value) | 해당 맵에서 전달된 키에 대응하는 값을 특정 값으로 대체함. |
boolean replace(K key, V oldValue, V newValue) | 해당 맵에서 특정 값에 대응하는 전달된 키의 값을 새로운 값으로 대체함. |
int size() | 해당 맵의 매핑의 총 개수를 반환함. |
[예시 코드]
![]() |
![]() |
[출력]
![]() |
2) Hashtable <K, V> 클래스
[특징]
- Hashtable 클래스는 JDK 1.0부터 사용해 온 HashMap 클래스와 같은 동작을 하는 클래스
- 현재에는 기존 코드와의 호환성을 위해서만 남아있으므로, Hashtable 클래스보다는 HashMap 클래스를 사용하는 것이 좋음.
3) TreeMap <K, V> 클래스
[특징]
- TreeMap 클래스는 키와 값을 한 쌍으로 하는 데이터를 이진 검색 트리(binary search tree)의 형태로 저장
- 이진 검색 트리는 데이터를 추가하거나 제거하는 등의 기본 동작 시간이 매우 빠름
- JDK 1.2부터 제공된 TreeMap 클래스는 NavigableMap 인터페이스를 기존의 이진 검색 트리의 성능을 향상한 레드-블랙 트리(Red-Black tree)로 구현.
- TreeMap 클래스는 Map 인터페이스를 구현하므로, 중복된 키로는 값을 저장할 수 없음.
- 같은 값을 다른 키로 저장하는 것은 가능.
[주요 메소드]
메소드 | 설명 |
Map.Entry<K,V> ceilingEntry(K key) | 해당 맵에서 전달된 키와 같거나, 전달된 키보다 큰 키 중에서 가장 작은 키와 그에 대응하는 값의 엔트리를 반환함. 만약 해당하는 키가 없으면 null을 반환함. |
K ceilingKey(K key) | 해당 맵에서 전달된 키와 같거나, 전달된 키보다 큰 키 중에서 가장 작은 키를 반환함. 만약 해당하는 키가 없으면 null을 반환함. |
void clear() | 해당 맵(map)의 모든 매핑(mapping)을 제거함. |
boolean containsKey(Object key) | 해당 맵이 전달된 키를 포함하고 있는지를 확인함. |
boolean containsValue(Object value) | 해당 맵이 전달된 값에 해당하는 하나 이상의 키를 포함하고 있는지를 확인함. |
NavigableMap<K, V> descendingMap() | 해당 맵에 포함된 모든 매핑을 역순으로 반환함. |
Set<Map.Entry<K, V>> entrySet() | 해당 맵에 포함된 모든 매핑을 Set 객체로 반환함. |
Map.Entry<K, V> firstEntry() | 해당 맵에서 현재 가장 작은(첫 번째) 키와 그에 대응하는 값의 엔트리를 반환함. |
K firstKey() | 해당 맵에서 현재 가장 작은(첫 번째) 키를 반환함. |
Map.Entry<K, V> floorEntry(K key) | 해당 맵에서 전달된 키와 같거나, 전달된 키보다 작은 키 중에서 가장 큰 키와 그에 대응하는 값의 엔트리를 반환함. 만약 해당하는 키가 없으면 null을 반환함. |
K floorKey(K key) | 해당 맵에서 전달된 키와 같거나, 전달된 키보다 작은 키 중에서 가장 큰 키를 반환함. 만약 해당하는 키가 없으면 null을 반환함. |
V get(Object key) | 해당 맵에서 전달된 키에 대응하는 값을 반환함. 만약 해당 맵이 전달된 키를 포함한 매핑을 포함하고 있지 않으면 null을 반환함. |
SortedMap<K, V> headMap(K toKey) | 해당 맵에서 전달된 키보다 작은 키로 구성된 부분만을 반환함. |
Map.Entry<K, V> higherEntry(K key) | 해당 맵에서 전달된 키보다 작은 키 중에서 가장 큰 키와 그에 대응하는 값의 엔트리를 반환함. 만약 해당하는 키가 없으면 null을 반환함. |
K higherKey(K key) | 해당 맵에서 전달된 키보다 작은 키 중에서 가장 큰 키를 반환함. 만약 해당하는 키가 없으면 null을 반환함. |
Set<K> keySet() | 해당 맵에 포함되어 있는 모든 키로 만들어진 Set 객체를 반환함. |
Map.Entry<K, V> lastEntry() | 해당 맵에서 현재 가장 큰(마지막) 키와 그에 대응하는 값의 엔트리를 반환함. |
K lastKey() | 해당 맵에서 현재 가장 큰(마지막) 키를 반환함. |
Map.Entry<K, V> lowerEntry(K key) | 해당 맵에서 전달된 키보다 큰 키 중에서 가장 작은 키와 그에 대응하는 값의 엔트리를 반환함. 만약 해당하는 키가 없으면 null을 반환함. |
K lowerKey(K key) | 해당 맵에서 전달된 키보다 큰 키 중에서 가장 작은 키를 반환함. 만약 해당하는 키가 없으면 null을 반환함. |
Map.Entry<K, V> pollFirstEntry() | 해당 맵에서 현재 가장 작은(첫 번째) 키와 그에 대응하는 값의 엔트리를 반환하고, 해당 엔트리를 맵에서 제거함. |
Map.Entry<K, V> pollLastEntry() | 해당 맵에서 현재 가장 큰(마지막) 키와 그에 대응하는 값의 엔트리를 반환하고, 해당 엔트리를 맵에서 제거함. |
V put(K key, V value) | 해당 맵에 전달된 키에 대응하는 값으로 특정 값을 매핑함. |
V remove(Object key) | 해당 맵에서 전달된 키에 대응하는 매핑을 제거함. |
boolean remove(K key, V value) | 해당 맵에서 특정 값에 대응하는 특정 키의 매핑을 제거함. |
V replace(K key, V value) | 해당 맵에서 전달된 키에 대응하는 값을 특정 값으로 대체함. |
boolean replace(K key, V oldValue, V newValue) | 해당 맵에서 특정 값에 대응하는 전달된 키의 값을 새로운 값으로 대체함. |
int size() | 해당 맵의 매핑의 총 개수를 반환함. |
SortedMap<K, V> subMap(K fromKey, K toKey) | 해당 맵에서 fromKey부터 toKey까지로 구성된 부분만을 반환함. 이때 fromKey는 포함되나, toKey는 포함되지 않음. |
SortedMap<K, V> tailMap(K fromKey) | 해당 맵에서 fromKey와 같거나, fromKey보다 큰 키로 구성된 부분만을 반환함. |
9. 참고
[Java] Java Collection 구조 정리
자바의 Collection 자료구조 자바에서 사용하는 컬렉션 프레임워크의 주요 클래스표이다. 좀더 상세한 클래스와 구현 인터페이스는 아래와 같다 1. Collection Interface Iterator 인터페이스를 상속한 Col
bangu4.tistory.com
[Java] 자바 컬렉션 프레임워크(List, Set, Map) 총정리
컬렉션 프레임워크란? 배열을 사용하다 보면 여러가지 비효율적인 문제가 생깁니다. 가장 큰 문제점은 크기가 고정적이라는 것입니다. 배열의 크기는 생성할 때 결정되며 그 크기를 넘어가게
coding-factory.tistory.com
코딩교육 티씨피스쿨
4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등
tcpschool.com