💡 JCF란?
- JCF(Java Collection FrameWork) : 자료 구조 종류의 형태들을 자바 클래스로 구현한 모음집
- JCF의 계층 구조
➜ List, Queue, Set과 달리 Map은 두개의 데이터를 묶어 한쌍으로 다루기 때문에 Collection 클래스와는 분리되어 있다.
➜ Vector, Stack, HashTable과 같은 클래스들은 레거시 임으로 사용 하지 않는다
💡 List 인터페이스 (ArrayList., LinkedList, Vector)
- 순서가 있는 데이터 집합
- 같은 요소의 중복 저장 허용
- 배열과 마찬가지로 index로 접근
- List vs 배열 : 리스트는 자료형 크기가 고정이 아니라 데이터 양에 따라 동적으로 늘어났다 주는것에 반해 배열은 고정되어 있다.
- 내부적으로 요소 사이에 빈공간을 허용하지 않아 삽입 삭제 할때마다 배열 이동이 일어난다.
(ArrayList 클래스)
- 배열을 기반으로 만든 List
- 데이터량에 따라 특정 양을 넘어서면 공간이 자동으로 늘었다가 줄음
- 조회가 빠르다, But 데이터를 삽입, 삭제 할 때 모든 데이터를 밀고 당겨야 해서 삽입 삭제 성능이 느리다
- Thread Safe 하지 않음
(LinkedList 클래스)
- 노드를 기반으로 민든 리스트
- 자바의 LinkedList의 노드는 양방향 포인터 구조로 되어 있다
- 데이터를 삽입, 삭제 할 경우, 그냥 노드를 끼워 넣으면 되기 때문에 빠르다. But 조회의 경우 앞에서부터 타고 가면서 찾아야 하기 때문에 성능이 느리다.
- Thread Safe 하지 않음
- 기본적으로 LinkedList로 구성 되어 있는데, 데이터가 일정 이상으로 들어오면 Red Black Tree로 자료구조가 변경된다.
ArrayList, LinkedList를 Thread Safe 하게 사용하려면?
1. Collections.synchronizedList() 사용
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
2. CopyOnWriteArrayList 사용
List<String> threadSafeList = new CopyOnWriteArrayList<>();
(Vector 클래스)
- 레거시로 이제 사용하지 않는다
- 모든 메서드가 동기화 되어 있어 Thread Safe 하다
💡 Queue 인터페이스 (PriorityQueue, Deque, ArrayDeque)
- 선입선출 FIFO(First-In-First-Out) 구조
(PriorityQueue 클래스)
- 우선순위를 가지는 큐
- 우선순위가 높은 순으로 정렬되고 꺼낸다
- 우선순위 큐에 저장할 객체는 Comparable 클래스를 구현 해야 함
(Deque 인터페이스)
- 앞뒤 다 넣고 빼는것이 가능한 큐
(ArrayDeque 클래스)
- Deque의 구현체
Deque<Integer> deque = new ArrayDeque<>();
deque.offerLast(100); // [100]
deque.offerFirst(10); // [10, 100]
deque.offerFirst(20); // [20, 10, 100]
deque.offerLast(30); // [20, 10, 100, 30]
deque.pollFirst(); // 20 <- [10, 100, 30]
deque.pollLast(); // [10, 100] -> 30
deque.pollFirst(); // 10 <- [100]
deque.pollLast(); // [] -> 100
💡 Set 인터페이스 (HashSet, LinkedHashSet, TreeSet)
- 데이터의 중복을 허용하지 않고 순서를 유지하지 않는 데이터의 집합
- 순서 자체가 없으므로 인덱스로 객체를 검색해서 가져오는 get(index) 메서드도 존재하지 않는다
- null도 중복으로 쳐서 null도 하나만 저장 가능
- Hashcode를 기반으로 중복을 판단하기 때문에 hashCode()를 적절히 재정의 하지 않은 경우 문제가 발생할 수도 있다.
(HashSet 클래스)
- Hash 기반으로 구현된, 아무 추가 기능이 없는 Set
- Set의 기본 특성인 데이터 중복을 허용하지 않는 속성만 가지고 있음
- 순서를 전혀 예측할 수 없다
Set<Integer> hashSet = new HashSet<>();
hashSet.add(10);
hashSet.add(20);
hashSet.add(30);
hashSet.add(10); // 중복된 요소 추가
hashSet.size(); // 3 - 중복된건 카운트 X
hashSet.toString(); // [20, 10, 30] - 자료 순서가 뒤죽박죽
(LinkedHashSet 클래스)
- Hash 기반으로 구현된, 순서를 가지는 Set
- 순서가 삽입된 순서이다
public class LinkedHashSetExample {
public static void main(String[] args) {
Set<String> linkedHashSet = new LinkedHashSet<>();
// 요소 추가
linkedHashSet.add("Apple");
linkedHashSet.add("Banana");
linkedHashSet.add("Cherry");
linkedHashSet.add("Apple"); // 중복 요소 (무시됨)
// 요소 출력 (삽입 순서 유지) - [Apple, Banana, Cherry]
System.out.println("LinkedHashSet: " + linkedHashSet);
}
}
(TreeSet 클래스)
- 이진 검색 트리 자료구조의 형태로 데이터를 저장
- 중복 허용 X, 요소를 오름차순(default)으로 정렬
- null 값 허용하지 않음
public class TreeSetExample {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<>();
set.add(30);
set.add(10);
set.add(20);
set.add(10); // 중복된 값은 무시됨
System.out.println(set); // [10, 20, 30] - 정렬된 순서
}
}
💡 Map 인터페이스 (HashMap, LinkedHashMap, TreeMap)
- 키(Key)와 값(value)의 쌍으로 연관지어 이루어진 데이터의 집합
- 값(value)은 중복되서 저장될 수 있지만, 키(key)는 해당 Map에서 고유해야만 한다
- 기존에 저장된 데이터와 중복된 키로 다른 값을 한번 더 저장하면, 이전 값이 새로운 값으로 덮어씌워진다
(HashMap)
- 중복을 허용하지 않고 순서를 보장하지 않는다
- 멀티 스레드 환경에서는 ConcurrentHashMap을 사용하자
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
// 데이터 추가
map.put("Alice", 25);
map.put("Bob", 30);
map.put("Charlie", 35);
System.out.println("Alice의 나이: " + map.get("Alice")); // 출력: Alice의 나이: 25
System.out.println("Bob이 존재합니까? " + map.containsKey("Bob")); // 출력: Bob이 존재합니까? true
System.out.println("30이라는 나이가 존재합니까? " + map.containsValue(30)); // 출력: 30이라는 나이가 존재합니까? true
System.out.println("모든 키: " + map.keySet()); // 출력: 모든 키: [Alice, Bob, Charlie]
System.out.println("모든 값: " + map.values()); // 출력: 모든 값: [25, 30, 35]
map.remove("Charlie");
System.out.println("Charlie 삭제 후: " + map);
System.out.println("HashMap 크기: " + map.size()); // 출력: HashMap 크기: 2
}
}
+ HashMap은 해시함수를 이용하여 Key값을 특정 인덱스(해시값)으로 변환하고, 빈 공간 내에 해시 값을 저장한다.
(LinkedHashMap)
- 일반적으로 Map 자료구조는 순서를 가지지 않지만, LinkedHashMap은 들어온 순서대로 순서를 가진다.
public static void main(String[] args) {
LinkedHashMap<Integer, String> map = new LinkedHashMap<>();
// 데이터 삽입
map.put(3, "Three");
map.put(1, "One");
map.put(2, "Two");
// 데이터 출력 (삽입 순서 유지) - {3=Three, 1=One, 2=Two}
System.out.println("LinkedHashMap 내용: " + map);
}
(TreeMap)
- Key 값을 기준으로 정렬된다.
public static void main(String[] args) {
// TreeMap 생성
TreeMap<Integer, String> map = new TreeMap<>();
// 데이터 삽입
map.put(3, "Three");
map.put(1, "One");
map.put(2, "Two");
// 데이터 출력 (정렬된 순서 유지) - {1=One, 2=Two, 3=Three}
System.out.println("TreeMap 내용: " + map);
}
💡 Iterable 인터페이스
- Iterable 인터페이스는 iterator를 반환하는 iterator() 추상 메서드가 있음
- iterator() 사용법
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
Iterator<String> iterator = list.iterator();
System.out.println("List 내용:");
while (iterator.hasNext()) { // 요소가 있는지 확인
System.out.println(iterator.next()); // 다음 요소 반환
iterator.remove(); // 요소 삭제
}
}
}
💡 Collections 클래스
- Collections는 Collection 조작을 위한 유틸리티 클래스
- Collections 클래스 사용법
public class Main {
public static void main(String[] args) {
// 1. 초기 리스트 생성
List<Integer> numbers = new ArrayList<>();
numbers.add(5);
numbers.add(2);
numbers.add(8);
numbers.add(1);
numbers.add(3);
// Original list: [5, 2, 8, 1, 3]
System.out.println("Original list: " + numbers);
// 2. 정렬 (sort)
Collections.sort(numbers);
// Sorted list: [1, 2, 3, 5, 8]
System.out.println("Sorted list: " + numbers);
// 3. 리스트 순서 뒤집기 (reverse)
Collections.reverse(numbers);
// Reversed list: [8, 5, 3, 2, 1]
System.out.println("Reversed list: " + numbers);
// 4. 최소값과 최대값 찾기 (min, max)
int min = Collections.min(numbers);
int max = Collections.max(numbers);
// Min: 1, Max: 8
System.out.println("Min: " + min + ", Max: " + max);
// 5. 리스트를 무작위로 섞기 (shuffle)
Collections.shuffle(numbers);
// Shuffled list: [3, 8, 5, 1, 2]
System.out.println("Shuffled list: " + numbers);
// 6. 동기화된 리스트 생성 (synchronizedList)
List<Integer> synchronizedList = Collections.synchronizedList(numbers);
synchronized (synchronizedList) {
System.out.println("Synchronized list: " + synchronizedList);
}
// 7. 수정 불가능한 리스트 생성 (unmodifiableList)
List<Integer> unmodifiableList = Collections.unmodifiableList(numbers);
System.out.println("Unmodifiable list: " + unmodifiableList);
// 아래 코드를 실행하면 UnsupportedOperationException 발생
// unmodifiableList.add(10);
}
}
🧱 Java Collections Framework 종류 💯 총정리
Java Collection Framework 자바 새내기분들은 컬렉션 프레임워크라는 단어에 뭔가 거창하고 어려운 느낌이 들수 있겠지만, 그냥 자료 구조(Data Structure) 종류의 형태들을 자바 클래스로 구현한 모음집
inpa.tistory.com
'Java' 카테고리의 다른 글
[JAVA] 가비지 컬렉션 (2) | 2025.01.30 |
---|---|
[JAVA] 동시성 프로그래밍 (0) | 2025.01.24 |
[JAVA] 문자열, 예외, 제네릭, 람다, 스트림, 어노테이션, 리플렉션 (0) | 2025.01.06 |
[JAVA] 자바 기본, 자바 객체 지향 (1) | 2025.01.03 |