[Java] 컬렉션 프레임워크(ArrayList · HashSet · TreeSet · HashMap · TreeMap) 정리

지현·3일 전

부트캠프 TIL - HTML

목록 보기
8/9

ArrayList · HashSet · TreeSet · HashMap · TreeMap

오늘 자바의 자료구조인 컬렉션 프레임워크(ArrayList, HashSet, TreeSet, HashMap, TreeMap)를 공부했다. 수많은 메서드가 있지만, 가장 많이 쓰이는 위주로 정리해 보았다.


📁 컬렉션 정리


구분구현 클래스특징중복 허용정렬/순서
ListArrayList인덱스로 관리하는 동적 배열입력 순서 유지
SetHashSet집합 개념, 빠른 검색 속도
SetTreeSet이진 트리 구조의 집합값 기준 정렬
MapHashMapKey-Value 쌍으로 저장Key ❌
MapTreeMapKey-Value 쌍 + 자동 정렬Key ❌키 기준 정렬


🔍 메서드 정리

List & Set 공통 메서드

메서드설명
add(E e)요소 추가
remove(Object o)요소 삭제
contains(Object o)포함 여부 확인 (있으면 true)
size()요소 개수 반환
clear()모든 요소 삭제
isEmpty()비어있으면 true

List<String> list = new ArrayList<>();
list.add("Apple");        // [Apple]
list.add("Banana");       // [Apple, Banana]
list.remove("Apple");     // [Banana]
list.contains("Banana");  // true
list.size();              // 1
list.isEmpty();           // false
list.clear();             // []

Set<String> set = new HashSet<>();
set.add("Apple");
set.add("Apple");  // 중복 → 무시됨
set.size();        // 1

List 전용 메서드

Set은 순서가 없어 인덱스 개념이 없으므로 아래 메서드는 List에서만 사용할 수 있다.

메서드설명
get(int index)해당 인덱스의 요소 반환
set(int index, E e)해당 인덱스의 요소를 교체
indexOf(Object o)요소의 첫 번째 인덱스 반환 (없으면 -1)

List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");

list.get(0);               // "Apple"
list.set(1, "Blueberry");  // [Apple, Blueberry, Cherry]
list.indexOf("Cherry");    // 2
list.indexOf("Mango");     // -1 (없는 요소)

Map 메서드

키와 값을 쌍으로 저장하는 구조.

메서드설명
put(K key, V value)Key-Value 추가 (키 중복 시 값 덮어쓰기)
get(Object key)키에 해당하는 값 반환 (없으면 null)
remove(Object key)키에 해당하는 쌍 삭제
containsKey(Object key)키 존재 여부 확인
keySet()모든 키를 Set으로 반환
values()모든 값을 Collection으로 반환

Map<String, Integer> map = new HashMap<>();
map.put("홍길동", 90);
map.put("이순신", 85);
map.put("홍길동", 95);  // 키 중복 → 값 95로 덮어쓰기

map.get("홍길동");         // 95
map.get("강감찬");         // null (없는 키)
map.containsKey("이순신"); // true
map.keySet();              // [홍길동, 이순신]
map.values();              // [95, 85]
map.remove("이순신");      // 이순신 쌍 삭제

// keySet()으로 전체 순회
for (String key : map.keySet()) {
    System.out.println(key + " : " + map.get(key));
}

Tree 계열 전용 메서드 (TreeSet / TreeMap)

정렬이 보장되기 때문에 범위 검색최솟값/최댓값 조회가 가능.

메서드설명
first() / firstKey()가장 작은 값(키) 반환
last() / lastKey()가장 큰 값(키) 반환
subSet(from, to) / subMap(from, to)from 포함, to 미포함
headSet(to) / headMap(to)to 미만의 요소 반환
tailSet(from) / tailMap(from)from 이상의 요소 반환
// TreeSet 예제
TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(30); treeSet.add(10); treeSet.add(50); treeSet.add(20);
// 자동 정렬됨 → [10, 20, 30, 50]

treeSet.first();         // 10 (최솟값)
treeSet.last();          // 50 (최댓값)
treeSet.subSet(10, 40);  // [10, 20, 30] (40 미포함)
treeSet.headSet(30);     // [10, 20] (30 미포함)
treeSet.tailSet(20);     // [20, 30, 50]

// TreeMap 예제
TreeMap<String, Integer> treeMap = new TreeMap<>();
treeMap.put("banana", 2); treeMap.put("apple", 5); treeMap.put("cherry", 1);
// 키 기준 알파벳 정렬 → {apple=5, banana=2, cherry=1}

treeMap.firstKey();                 // "apple"
treeMap.lastKey();                  // "cherry"
treeMap.subMap("apple", "cherry"); // {apple=5, banana=2}

⚡ 성능 비교 Hash vs Tree

HashSet / HashMap은 해시 함수로 데이터 위치를 바로 찾아가기 때문에 O(1) 로 매우 빠르다.
반면 TreeSet / TreeMap은 데이터를 넣을 때마다 기존 데이터들과 비교해 정렬된 위치를 탐색하므로 O(log n) 의 비용이 발생한다.

컬렉션검색/삽입/삭제정렬사용 기준
HashSet / HashMapO(1)기본 선택 — 속도 우선
TreeSet / TreeMapO(log n)정렬이 꼭 필요할 때

정렬이 꼭 필요한 경우가 아니라면, Hash 계열을 사용하는 것이 기본 !


🔢 집합 연산 (Set)

Set은 수학의 집합과 동일한 개념이라 합집합, 교집합, 차집합 연산을 메서드 하나로 처리할 수 있다.

연산메서드설명
합집합 (A ∪ B)addAll(Collection c)다른 컬렉션의 요소를 모두 추가
교집합 (A ∩ B)retainAll(Collection c)다른 컬렉션과 공통된 요소만 남김
차집합 (A - B)removeAll(Collection c)다른 컬렉션에 있는 요소를 모두 제거

⚠️ 이 메서드들은 원본 Set을 직접 수정하므로 원본을 보존하려면 새로운 Set에 복사한 뒤 사용.

Set<Integer> A = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
Set<Integer> B = new HashSet<>(Arrays.asList(3, 4, 5, 6, 7));

// 합집합 (A ∪ B) → [1, 2, 3, 4, 5, 6, 7]
Set<Integer> union = new HashSet<>(A);
union.addAll(B);
System.out.println(union);

// 교집합 (A ∩ B) → [3, 4, 5]
Set<Integer> intersection = new HashSet<>(A);
intersection.retainAll(B);
System.out.println(intersection);

// 차집합 (A - B) → [1, 2]
Set<Integer> difference = new HashSet<>(A);
difference.removeAll(B);
System.out.println(difference);

결과를 정렬된 상태로 보고 싶다면 → TreeSet으로 변환

Set<Integer> A = new HashSet<>(Arrays.asList(5, 3, 1, 4, 2));
Set<Integer> B = new HashSet<>(Arrays.asList(3, 4, 5, 6, 7));

Set<Integer> union = new HashSet<>(A);
union.addAll(B);

System.out.println(union);               // HashSet → 순서 무작위
System.out.println(new TreeSet<>(union)); // TreeSet → 자동 정렬: [1, 2, 3, 4, 5, 6, 7]


😎 언제 어떤 컬렉션을 쓸까?

순서가 중요할 때 → List

List<String> playlist = new ArrayList<>();
playlist.add("노래 A");
playlist.add("노래 B");
playlist.add("노래 A");  // 중복 OK
System.out.println(playlist.get(0));  // 노래 A

중복 제거가 필요할 때 → Set

Set<String> visited = new HashSet<>();
visited.add("Seoul");
visited.add("Tokyo");
visited.add("Seoul");  // 중복 → 무시됨
System.out.println(visited.size());  // 2

관계(Key-Value)를 저장할 때 → Map

Map<String, Integer> score = new HashMap<>();
score.put("홍길동", 90);
score.put("이순신", 85);
System.out.println(score.get("홍길동"));  // 90

0개의 댓글