Java 컬렉션 프레임워크는 데이터를 효율적으로 저장하고 관리하기 위한 구조와 인터페이스의 집합입니다. 여러 데이터 구조를 제공하여 데이터를 다루기 쉽게 만들어주기 때문에 Java 개발 시 알아두어야 합니다.
컬렉션 프레임워크 계층도

Iterable 인터페이스
Iterable은 Java에서 반복 가능한 객체를 나타내는 최상위 인터페이스로, 컬렉션이 요소들을 순차적으로 탐색할 수 있도록 정의한 인터페이스입니다. 컬렉션을 foreach로 사용할 수 있게 하는 것이 바로 이 인터페이스 덕분입니다.
List<String> fruits = Arrays.asList("Apple", "Banana", "Cherry"); for (String fruit : fruits) { System.out.println(fruit); // Apple, Banana, Cherry }
위 코드처럼 Collection 인터페이스를 구현한 모든 클래스는 Iterable인터페이스도 구현했기 때문에, foreach로 반복문을 사용할 수 있습니다. 추가로 Collection 인터페이스를 구현한 클래스들은 iterator() 메서드를 사용하여 Iterator를 반환하여 사용할 수 있습니다.
주요 메서드
- hasNext(): 다음 요소가 존재하면 true를 반환합니다.
- next(): 다음 요소를 가져옵니다.
- remove(): 가져온 요소 삭제합니다. 가져온 요소를 삭제할 수 있기 때문에 next()가 먼저 선행되어야 합니다.
Iterator<String> iterator = list.iterator(); while(iterator.hasNext()) { String s = iterator.next(); iterator.remove(); }
Collection<E>
- 기본 인터페이스로, 대부분의 컬렉션 클래스가 이 인터페이스를 상속받습니다.
- 하위 인터페이스로 List, Queue, Set 등이 있습니다.
주요 메서드
- boolean add(Object o): 컬렉션에 요소를 추가합니다.
- boolean addAll(Collection<? extends E> c): 주어진 컬렉션의 모든 요소를 추가합니다.
- boolean remove(Object o): 지정된 요소를 컬렉션에서 제거합니다.
- boolean removeAll(Collection<?> c): 주어진 컬렉션에 포함된 모든 요소를 현재 컬렉션에서 제거합니다.
- boolean retainAll(Collection<?> c): 주어진 컬렉션에 포함된 요소만 남기고, 나머지 요소를 제거합니다.
- boolean contains(Object o): 컬렉션에 지정된 객체가 포함되어 있으면 true를 반환합니다.
- boolean containsAll(Collection<?> c): 컬렉션이 지정된 컬렉션의 모든 요소를 포함하고 있으면 true를 반환합니다.
- int size(): 컬렉션에 포함된 요소의 수를 반환합니다.
- boolean isEmpty(): 컬렉션이 비어 있으면 true를 반환합니다.
- void clear(): 컬렉션의 모든 요소를 제거합니다.
- boolean equals(Object o): 컬렉션과 지정된 객체가 동일한지 비교합니다.
- int hashCode(): 컬렉션의 해시 코드를 반환합니다.
- Iterator<E> iterator(): 컬렉션의 요소들을 순차적으로 탐색할 수 있는 Iterator를 반환합니다.
- Object[] toArray(): 컬렉션의 요소를 배열로 반환합니다.
- <T> T[] toArray(T[] a): 컬렉션의 요소를 지정된 타입의 배열로 반환합니다.
List<E>
- 순서가 있는 요소의 컬렉션입니다. 요소들은 인덱스에 의해 관리됩니다.
- 구현 클래스: ArrayList, LinkedList, Vector
주요 메서드
List 인터페이스는 Collection 인터페이스에서 상속받은 메소드 외에 아래와 같은 추가 메소드를 제공합니다.
- void add(int index, E element): 지정된 위치에 요소를 삽입합니다.
- boolean addAll(int index, Collection<? extends E> c): 특정 위치에 컬렉션의 모든 요소를 삽입합니다.
- E remove(int index): 지정된 인덱스의 요소를 제거합니다.
- E get(int index): 지정된 인덱스의 요소를 반환합니다.
- E set(int index, E element): 지정된 인덱스의 요소를 지정된 요소로 교체합니다.
- int indexOf(Object o): 리스트에서 처음으로 해당 객체가 나타나는 인덱스를 반환합니다.
- int lastIndexOf(Object o): 리스트에서 마지막으로 해당 객체가 나타나는 인덱스를 반환합니다.
- ListIterator<E> listIterator(): 리스트의 요소에 순차적으로 접근하기 위한 ListIterator를 반환합니다.
- ListIterator<E> listIterator(int index): 지정된 인덱스부터 탐색을 시작하는 ListIterator를 반환합니다.
- List<E> subList(int fromIndex, int toIndex): 지정된 범위의 요소로 이루어진 부분 리스트를 반환합니다.
- void Sort(Comparator c): 지정된 비교자(comparator)로 List를 정렬합니다.
ArrayList<E>
동적 배열을 사용하여 요소를 관리하며, 인덱스를 통한 접근이 빠릅니다. 요소의 삽입 및 삭제는 상대적으로 느립니다.
추가 메서드
- trimToSize(): 내부 배열의 용량을 현재 요소의 크기(개수)로 조정합니다.
- ensureCapacity(int minCapacity): 내부 배열의 용량을 최소한 지정된 용량으로 늘립니다.
LinkedList<E>
이중 연결 리스트로 구현되어 삽입 및 삭제가 빠릅니다. 인덱스를 통한 접근은 느립니다.
추가 메서드
- void addFirst(E e): 리스트의 처음에 요소를 추가합니다.
- void addLast(E e): 리스트의 끝에 요소를 추가합니다.
- E getFirst(): 첫 번째 요소를 반환합니다.
- E getLast(): 마지막 요소를 반환합니다.
- E removeFirst(): 첫 번째 요소를 제거합니다.
- E removeLast(): 마지막 요소를 제거합니다.
Vector<E>
ArrayList와 유사하지만, 모든 메서드가 동기화되어 있어 스레드 안전합니다. 하지만 Vector의 메서드는 항상 동기화로 인해 오버헤드가 발생해 성능 저하가 발생합니다. Vector는 성능 저하 뿐 아니라 내부적으로 안정하지 않아 현재 deprecated 된 클래스입니다.
Queue<E>
- Queue는 먼저 들어온 데이터가 먼저 나가는 선입선출, 즉 FIFO (First In First Out) 구조를 따릅니다. 대기열 구조에 적합합니다.
- 구현 클래스: LinkedList, PriorityQueue, ArrayDeque
주요 메서드
- boolean add(Object o): 큐의 끝에 요소를 추가합니다. (저장 공간이 부족할 때, IllegalStateException 발생합니다.)
- boolean offer(Object o): 큐의 끝에 요소를 추가합니다. (저장 공간이 부족할 때, add()와 달리 예외를 발생시키지 않음)
- E poll(): 큐의 앞에서 요소를 제거하고 반환합니다, 큐가 비어있으면 null을 반환합니다.
- E peek(): 큐의 앞에 있는 요소를 반환하지만 제거하지는 않습니다. 큐가 비어있으면 null을 반환합니다.
- E remove(): 큐의 앞에서 요소를 제거하고 반환합니다. 큐가 비어 있으면 예외를 발생시킵니다.
- E element(): 큐의 앞에 있는 요소를 반환하지만 제거하지는 않습니다. 큐가 비어 있으면 예외를 발생시킵니다.
LinkedList<E>
LinkedList는 List와 Deque 인터페이스를 모두 구현하였기 때문에 List 뿐만 아니라 Queue로 사용할 수 있습니다.
Queue<Integer> q = new LinkedList<>();
PriorityQueue<E>
PriorityQueue는 들어온 데이터 순서 상관없이 데이터의 우선순위에 따라 데이터가 나가는 구조입니다. 요소에 우선순위를 지정하지 않으면 기본형(우선순위가 낮은 숫자) 순서대로 정렬되고, 우선순위를 지정하면(Comparator 등) 이에 따라 정렬됩니다.
// 기본형: 우선순위가 낮은 순 (작은 숫자부터) PriorityQueue<Integer> pQ = new PriorityQueue<>(); // 우선순위가 높은 순 (높은 숫자부터) PriorityQueue<Integer> pQ = new PriorityQueue<>(Collections.reverseOrder());
Set<E>
- 중복을 허용하지 않는 요소의 컬렉션입니다.
- 요소의 순서는 보장되지 않습니다.
- 구현 클래스: HashSet, TreeSet, LinkedHashSet
- LinkedHashSet은 요소가 삽입된 순서를 기억하고, TreeSet은 요소를 정렬합니다.
주요 메서드
Set<E> 인터페이스는 Collection<E>의 메서드만을 상속받아 사용하며, 추가적인 메서드는 제공하지 않습니다. 하지만 각 구현 클래스는 고유한 특징과 메서드를 갖고 있습니다.
HashSet<E>
해시 테이블을 기반으로 구현되어 빠른 요소 접근이 가능합니다. 요소의 순서를 보장하지 않습니다.
추가 메서드
- boolean add(E e): 요소를 추가합니다.
- boolean addAll(Collection c): 주어진 컬렉션에 저장된 모든 객체들을 추가합니다.
- boolean contains(Object o): 요소의 존재 여부를 확인합니다.
- boolean conatainsAll(Collection c): 주어진 컬렉션에 저장된 모든 객체들을 포함하고 있는지 확인합니다.
- boolean remove(Object o): 요소를 제거합니다.
- boolean removeAll(Collection c): 주어진 컬렉션에 저장된 모든 객체와 동일한 요소들을 제거합니다.
- boolean isEmpty(): HashSet이 비어있는지 확인합니다.
- int size(): 요소의 개수를 반환합니다.
- void clear(): 저장된 모든 객체를 삭제합니다.
LinkedHashSet<E>
HashSet과 유사하지만, 요소의 삽입 순서를 유지합니다.
TreeSet<E>
TreeSet은 정렬된 집합을 제공하며, 내부적으로 이진 탐색 트리로 구현됩니다 중복을 허용하지 않으며, 삽입된 요소가 자동으로 정렬됩니다.
추가 메서드
- E first(): 첫 번째(가장 작은) 요소를 반환합니다.
- E last(): 마지막(가장 큰) 요소를 반환합니다.
- E lower(E e): 지정된 요소보다 작은 요소 중 가장 큰 것을 반환합니다.
- E higher(E e): 지정된 요소보다 큰 요소 중 가장 작은 것을 반환합니다.
- SortedSet<E> subSet(E fromElement, E toElement): 부분 집합을 반환합니다.
Map<K, V>
- 키-값 쌍을 저장하는 구조입니다. 키는 중복을 허용하지 않지만, 값은 중복 가능합니다.
- 구현 클래스: HashMap, TreeMap, LinkedHashMap, Hashtable
주요 메서드
- V put(K key, V value): 지정된 키와 값을 맵에 추가합니다. 키가 중복되는 경우 덮어쓰기 됩니다.
- V get(Object key): 지정된 키에 매핑된 값을 반환합니다. 키가 없으면 null을 반환합니다.
- V remove(Object key): 해당 키에 연결된 값을 삭제하고 반환합니다.
- boolean containsKey(Object key): 지정된 키가 존재하면 true를 반환합니다.
- boolean containsValue(Object value): 지정된 값이 존재하면 true를 반환합니다.
- V putIfAbsent(K key, V value): 해당 키가 없을 때만 키-값 쌍을 추가합니다.
- void putAll(Map<? extends K, ? extends V> m): 다른 맵에 있는 모든 키-값 쌍을 현재 맵에 추가합니다.
- void clear(): 맵의 모든 요소를 제거합니다.
- int size(): 맵에 있는 키-값 매핑의 수를 반환합니다.
- boolean isEmpty(): 맵이 비어 있으면 true를 반환합니다.
- Set<K> keySet(): 맵의 모든 키를 포함하는 Set을 반환합니다.
- Collection<V> values(): 맵에 존재하는 모든 값을 반환합니다.
- Set<Map.Entry<K, V>> entrySet(): 맵의 모든 키-값 쌍을 포함하는 Map.Entry 객체의 집합(Set)을 반환합니다.
// keySet() 예시 Set<String> keys = map.keySet(); for (String key : keys) { System.out.println("Key: " + key + ", Value: " + map.get(key)); } // entrySet() 예시 for (Map.Entry<String, Integer> entry : map.entrySet()) { String key = entry.getKey(); Integer value = entry.getValue(); System.out.println("Key: " + key + ", Value: " + value); }
HashMap<K, V>
해시 테이블을 기반으로 구현되어 빠른 검색과 삽입이 가능합니다. 순서를 보장하지 않고, key와 value에 null을 허용합니다.
HashMap에서는 key값을 전달하면 HashMap에서는 이 key를 hash로 바꾸어 고유키로 사용합니다. key 값이 null인 경우 HashMap에서는 0을 고유키로 사용하고, 나머지는 hash로 처리합니다.
LinkedHashMap<K, V>
HashMap과 유사하지만, 삽입 순서를 유지합니다.
TreeMap<K, V>
TreeMap은 정렬된 맵을 제공하며, 키들이 자동 정렬됩니다. 내부적으로 이진 탐색 트리로 구현되고, 키는 Comparable을 구현하거나 Comparator를 제공해야합니다.
Hashtable<K, V>
Hashtable은 스레드 안전한 해시 기반의 맵입니다. HashMap과 유사하지만, 모든 메서드가 동기화되어 있어 멀티스레드 환경에서 사용할 수 있습니다.
자바의 기본적인 컬렉션 클래스들은 멀티스레드 환경에서 안전하지 않기 때문에 멀티스레드 환경에서 컬렉션을 안전하게 사용하기 위해 동기화된 방식으로 동작하는 컬렉션을 사용해야합니다. 이에 대한 글은 바로 다음에 포스팅하겠습니다.
'Java' 카테고리의 다른 글
Java 제네릭(Generic) & 와일드카드 완벽 이해하기 (0) | 2024.10.05 |
---|---|
Java 멀티스레드 환경에서 Collection 사용: 동기화된 컬렉션과 Concurrent 컬렉션 (1) | 2024.09.26 |
Java 날짜 및 시간 포맷 다루기. SimpleDateFormat, DateTimeFormatter, FastDateFormat (1) | 2024.09.24 |
Java 날짜 시간 다루기: LocalDateTime, Instant, OffsetDateTime, ZonedDateTime의 차이. Duration, Period (0) | 2024.09.23 |
Java 예외 처리 완벽 이해하기 (0) | 2024.09.19 |