반응형
여승철
INTP 개발자
여승철
  • 분류 전체보기 (376)
    • CS (16)
      • 면접 준비 (7)
      • 운영체제 (0)
      • 네트워크 (2)
      • HTTP (6)
      • 스프링(Spring) IoC 컨테이너 (0)
      • 알고리즘 (1)
    • Web (13)
    • AWS (6)
    • Java (43)
    • JSP & Servlet (65)
      • 개념 (42)
      • 실습 (23)
    • Spring Framework (33)
    • Spring Boot (10)
    • Spring Data (22)
      • JPA (14)
      • Query DSL (7)
      • Redis (1)
    • Spring Security (9)
    • Spring Batch (4)
    • MyBatis (10)
    • Front-End (51)
      • JS (27)
      • Vue.js (17)
      • React (5)
      • JQuery (0)
      • d3.js (2)
    • DBMS (24)
      • SQL, RDBMS (16)
      • MongoDB (5)
      • Redis (3)
    • Kafka (3)
    • 리눅스 (Linux) (4)
    • 디자인 패턴 (3)
    • VCS (8)
    • API (0)
    • TOOL (3)
    • Reading Book (28)
      • 이펙티브 자바 (11)
      • Clean Code (10)
      • 1분 설명력 (4)
      • HOW TO 맥킨지 문제해결의 기술 (3)
    • C# (4)
    • NSIS (6)
    • ETC (11)

블로그 메뉴

  • 홈
  • 태그

인기 글

태그

  • EC2
  • 회원 관리
  • ubuntu
  • 이펙티브 자바
  • servlet
  • Spring Batch
  • HTTP
  • controller
  • querydsl
  • 스트림
  • 환경 세팅
  • 게시판
  • jsp
  • mybatis
  • 디자인 패턴
  • JSTL
  • JDBC
  • Dao
  • 로그인
  • 맥킨지

최근 댓글

최근 글

hELLO· Designed By 정상우.
여승철

INTP 개발자

Java 컬렉션 프레임워크 완벽 이해하기
Java

Java 컬렉션 프레임워크 완벽 이해하기

2024. 9. 26. 21:27
반응형

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

 

컬렉션 프레임워크 계층도

https://levelup.gitconnected.com/java-collections-framework-class-hierarchy-latest-2024-51f9154f1f57

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
    여승철
    여승철

    티스토리툴바