본문 바로가기

개발 언어 및 알고리즘 기초/JAVA 기초

[JAVA] Collection Framework 정리

 

자바 공부 중 Collection Framework에 대한 내용이 방대하다고 느껴져, 기억할 겸 정리한 것에 대한 기록이다. 아래 책을 공부 중이다.

신용권, 임경균, 『이것이 자바다』, 한빛미디어(2023), p120-121.

 

 

 

 0. Collection Framework (컬렉션 프레임워크) 

 Collection Framework란 널리 알려진 자료구조를 바탕으로 객체들을 효율적으로 추가, 삭제, 검색할 수 있도록 만들어진 각종 인터페이스와 클래스들이다. java.util 패키지에 포함되어 있다. 

 Collection Framework는 크게 세 가지로 분류할 수 있는데, List, Set 그리고 Map이 이에 해당한다. List와 Set이 유사하여 이는 Collection interface로 정의되고, Map은 따로 Map interface로 정의된다. Map의 가장 큰 차이점은 List와 Set이 단일 값이 저장된 객체를 가지는 것과는 달리 Map은 key와 값으로 구성된 Entry를 저장한다는 점이다. 그리고 List와 Set을 나누는 차이는 List는 순서를 유지하고 중복 저장을 허용하지만 Set은 순서를 무시하고 중복 저장을 허용하지 않는다는 점이다. 

 

 컬렉션들은 공통적으로 아래와 같은 방식으로 생성할 수 있다. (List collection에서 ArrayList를 예로 작성되었다.)

List<E> = new ArrayList<E>();   // E에 지정된 타입의 객체만 저장
List<E> = new ArrayList<>();     // E에 지정된 타입의 객체만 저장
List list = new ArrayList();          // 모든 타입의 객체를 저장

 

 

 

1. List Collection (리스트 컬렉션) 

 List Collection은 앞서 언급했듯 순서를 지켜 객체들을 저장하는 컬렉션에 해당한다. 각 객체에 인덱스를 부여하여 검색, 삭제할 수 있는 기능을 제공한다. 

 

List Collection에서 공통적으로 사용 가능한 List 인터페이스 메소드는 아래와 같다.

객체 추가 boolean add(E e) e를 맨 끝에 추가
void add(int index, E element) e를 index에 추가 (index부터 하나씩 밀림)
set(int index, E element) index 위치를 element로 대체
객체 검색 boolean contains(Object o) o가 포함되어 있는지 여부
E get(int index) index 위치의 객체를 리턴
isEmpty() 컬렉션이 비어있는지 여부
int size() 컬렉션 내 객체 수
객체 삭제 void clear() 모든 객체 삭제
E remove(int index) index 위치의 객체를 삭제
boolean remove(Object o) 주어진 객체 삭제

 

 

List Collection에는 아래와 같이 ArrayList, Vector, LinkedList 등이 있다.

Collection 특징 장점 단점
ArrayList  index 0번부터 차례로 저장하여 리스트  생성  인덱스 별로 검색에 용이  삽입과 삭제가 잦을 경우 효율이 좋지 않음 
Vector  ArrayList와 동일하지만 동기화된 메소드로 구성되어 멀티 스레드가 동시에 Vector() 메소드를 실행 불가  멀티 스레드 환경에서 안전하게 객체 추가/삭제 가능 (경합이 발생하지 않음)  삽입과 삭제가 잦을 경우 효율이 좋지 않음 
LinkedList 인접 객체를 체인처럼 연결하여 관리 삽입과 삭제에 용이 -

 

 

 

 

 2. Set Collection 

 Set Collection은 저장 순서를 유지하지 않고 객체들을 저장하는 컬렉션에 해당한다. 객체를 중복해서 저장할 수는 없다. 따라서 수학의 집합에 비유될 수 있다. 따라서 객체의 hashCode() 메소드 리턴값이 같고, equals() 메소드가 true를 리턴하면 동일한 객체라고 판단하고 중복 저장하지 않는다. 

 

 Set Collection에서 공통적으로 사용 가능한 List 인터페이스 메소드는 아래와 같다. 인덱스로 관리하지 않기 때문에 인덱스를 매개값으로 갖는 메소드는 없다.

객체 추가 boolean add(E e) e를 맨 끝에 추가 (성공 시 true, 실패 시 false 리턴)
객체 검색 boolean contains(Object o) o가 포함되어 있는지 여부
isEmpty() 컬렉션이 비어있는지 여부
Iterator<E> iterator() 저장된 객체를 한 번씩 가져오는 반복자 리턴
int size() 컬렉션 내 객체 수
객체 삭제 void clear() 모든 객체 삭제
boolean remove(Object o) 주어진 객체 삭제

 

 

 Set Collection에는 HashSet, LinkedHashSet, TreeSet 등이 있다.

 

 여기서 Set Collection은 index가 없기 때문에 iterator(반복자)를 사용하는데, 이는 다음 메소드를 제공한다. 아래의 hasNext() 메소드를 통해 남은 객체가 있는지 확인을 하면서, next() 메소드로 하나씩 객체를 가져오는 식으로 순회할 수 있다. 

boolean hasNext() 남은 가져올 객체가 있는지 여부
E next() Collection에서 하나의 객체를 가져옴
void remove() next()로 가져온 객체를 Set Collection에서 제거

 

 

 

 

 3. Map Collection 

 Map Collection은 key와 value로 구성된 entry 객체를 저장하는 형태이다. 여기서 key만 중복 저장이 불가능하다. value가 같더라도 key가 다르면 각각 저장이 가능하다. 만약 같은 key값이 한 번 더 추가되면, 새로운 값으로 대체된다.

 

Map Collection에서 공통적으로 사용 가능한 List 인터페이스 메소드는 아래와 같다.

객체 추가 V put(K key, V value) 주어진 key와 value를 추가하고 저장되면 value 리턴
객체 검색
boolean containsKey(Object key) 주어진 key가 포함되어 있는지 여부
boolean containsValue(Object value) 주어진 value가 포함되어 있는지 여부
Set<Map.Entry<K, V>> entrySet() key와 value의 쌍으로 구성된 모든 Map.Entry 객체를 Set에 담아 리턴
V get(Object key) 주어진 key값을 가진 value를 리턴
boolean isEmpty() Collection이 비어있는지 여부
Set<K> keySet() 모든 key 객체를 담은 Set을 리턴
int size() 저장된 키의 수를 리턴
Collection<V> values() 모든 value 객체를 담은 Collection을 리턴
객체 삭제 void clear() 모든 Map.Entry를 삭제
V remove(Object key) 주어진 key를 가진 Entry를 삭제

 

 

 Map Collection에는 아래와 같이 HashMap, Hashtable, LinkedHashMap, Properties, TreeMap 등이 있다.

Collection 특징
HashMap  key로 사용할 객체의 hashCode() 메소드 리턴값이 같고 equals() 리턴값이 true인 경우
중복 저장을 허용하지 않음 (즉, 키 값의 중복을 허용하지 않음)
Hashtable HashMap과 동일하지만 synchronized method로 구성되어 멀티 스레드가 동시에
Hashtable 메소드들을 실행할 수 없음 (즉, 경합이 발생하지 않아 안전하게 객체를 추가, 삭제 가능)
Properties Hashtable의 자식 객체이지만 key와 value를 String type으로 제한
(확장자가 .properties인 프로퍼티 파일을 읽을 때 주로 사용)

 

 

 

 

 (+) 검색 기능을 강화한 Binary Tree Collection 

 Collection Framework는 검색 기능을 강화한 TreeSet과 TreeMap을 제공한다. 이 두 컬렉션은 이진 트리(binary tree)를 기반으로 한 컬렉션들로, 여러 개의 노드(node)가 트리 형태로 연결되어 있다. 루트노드(root node)로 시작하여 각 노드가 최대 2개의 자식 노드를 가지는데, 각각 left node, right node를 가지는 것이다.

 이 타입의 collection을 생성할 때는 보통의 collection에서와는 다르게 Set이나 Map 타입 변수에 대입하지 않고, TreeSet과 TreeMap 타입 변수에 대입하는 편이 낫다. 왜냐하면 TreeSet과 TreeMap 타입만이 가지는 검색 관련 메소드들이 있기 때문이다. 

 

 TreeSet의 경우는 노드가 하나의 객체로 구성된다. TreeSet은 저장과 동시에 객체를 기준으로 오름차순으로 정렬된다. 부모 객체와 비교해서 낮은 것은 왼쪽, 높은 것은 오른쪽 자식 노드에 저장되는 방식이다. TreeSet이 가진 검색 관련 메소드들은 다음과 같다. 

특정 객체
가져오기
E first() 제일 낮은 객체를 리턴 (오름차순에서 첫번째 객체)
E last() 제일 높은 객체를 리턴 (오름차순에서 마지막 객체)
E lower(E e) 주어진 객체보다 바로 아래 객체를 리턴 (오름차순에서 주어진 객체보다 바로 앞순서 객체)
E highr(E e) 주어진 객체보다 바로 위 객체를 리턴 (오름차순에서 주어진 객체보다 바로 뒷순서 객체)
E floor(E e) 주어진 객체와 같거나 낮은 객체 하나 리턴
E ceiling(E e) 주어진 객체와 같거나 높은 객체 하나 리턴
E pollFirst() 제일 낮은 객체를 리턴하고 삭제
E pollLast() 제일 높은 객체를 리턴하고 삭제
내림차순
정렬하기
Iterator<E> descendingIterator() 내림차순으로 정렬된 Iterator 리턴
NavigableSet<E> descendingSet 내림차순으로 정렬된 NavigableSet을리턴
 
특정
range set
가져오기
 
NavigableSet<E> headSet(E toElement, boolean inclusive) toElement보다 낮은 객체들을 NavigableSet으로 리턴
(inclusive가 true일 때 toElement 포함) 
NavigableSet<E> tailSet(E fromElement, boolean inclusive)  fromElement보다 높은 객체들을 NavigableSet으로 리턴
(Inclusive가 true일 때 fromElement 포함)
NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement,
boolean toInclusive)
 from Element와 toElement 사이에 있는 객체들을
NavigableSet으로 리턴

 

 

 TreeMap은 노드가 key와 value로 구성된 Entry이다. TreeMap은 key를 기준으로 정렬된다. 부모 노드의 key와 비교해서 낮은 것은 왼쪽, 높은 것은 오른쪽 자식 노드에 Entry 객체를 저장한다. TreeMap이 가진 검색 관련 메소드들은 다음과 같다.

특정 Entry
가져오기
Map.Entry<K, V> firstEntry() 제일 낮은 Map.Entry를 리턴 (오름차순에서 첫번째 객체)
Map.Entry<K, V> lastEntry() 제일 높은 Map.Entry를 리턴 (오름차순에서 마지막 객체)
Map.Entry<K, V> lowerEntry(K key) 주어진 key보다 바로 아래 Map.Entry를 리턴
(오름차순에서 주어진 객체보다 바로 앞순서 객체)
Map.Entry<K, V> highrEntry(K k) 주어진 key보다 바로 위 Map.Entry를 리턴
(오름차순에서 주어진 객체보다 바로 뒷순서 객체)
Map.Entry<K, V> floorEntry(K key) 주어진 key와 같거나 낮은 Map.Entry 하나 리턴
Map.Entry<K, V> ceilingEntry(K key) 주어진 key와 같거나 높은 Map.Entry 하나 리턴
Map.Entry<K, V> pollFirstEntry() 제일 낮은 Map.Entry를 리턴하고 삭제
Map.Entry<K, V> pollLastEntry() 제일 높은 Map.Entry를 리턴하고 삭제
내림차순
정렬하기
Iterator<K> descendingKeySet() 내림차순으로 정렬된 key의 Iterator 리턴
NavigableMap<K, V> descendingMap() 내림차순으로 정렬된 Map.Entry의 NavigableSet을 리턴
 
특정
range set
가져오기
 
NavigableMap<K, V> headMap(K toKey,
boolean inclusive)
toKey보다 낮은 Map.Entry들을 NavigableMap으로 리턴
(inclusive가 true일 때 toKey를 가진 Map.Entry 포함) 
NavigableMap<K, V> tailMap(K fromKey, boolean inclusive)  fromKey보다 높은 Map.Entry들을 NavigableMap으로 리턴
(Inclusive가 true일 때 fromKey를 가진 Map.Entry 포함)
NavigableMap<K, V> subSet(K fromKey, boolean fromInclusive, K toKey,
boolean toInclusive)
 fromKey와 toKey사이에 있는 MapEntry들을
NavigableMap으로 리턴

 

 

 위와 같이 TreeSet과 TreeMap은 저장과 동시에 오름차순으로 정렬하기 때문에, 저장되는 객체들이 Comparable 인터페이스를 구현하고 있어야 한다. 즉, 비교 가능한 객체여야 한다. 만약 비교 가능한 객체가 아닌 경우에는 Comparable 인터페이스를 구현하여 CompareTo() 메소드를 Override하면 된다. 만약 Comaprable 비구현 객체를 저장하고 싶다면 TreeSet이나 TreeMap 생성 시에 비교자(Comparator 인터페이스를 구현한 객체)를 제공하면 된다. 

728x90