[종합] Collection 의 다양한 선택
http://cs.lmu.edu/~ray/notes/collections/
* 개요
동일한 기능의 컬렉션도 성능, 정렬 여부, 기타 세부 기능에 따라 나눠지며
동기화가 제공 되느냐에 따라 Concurrent 또는 Synchronized 가 되기도 한다.
언제까지 ArrayList 로 떡칠할 수 없으니 용도별 컬렉션 선택을 정리해봤다.
사용시 참고를 위해서 구현체를 기준으로 정리했다.
* 비동기화 - 동기화 - 병렬 컬렉션 차이
http://deepblue28.tistory.com/entry/Java-SynchronizedCollections-vs-ConcurrentCollections
- synchronized Collection (동기화 컬렉션)
Thread-safe 하지만, 동시 접근이 불가능해서 성능이 떨어진다.
또한 두개이상 연산을 묶어서 처리해주는 경우는 외부에서 동기화 처리 해줘야 한다.
예를 들면 put-if-absent = 데이터가 없는 경우에만 추가하는 연산의 경우
1. 데이터 가져오기 명령으로 데이터 없는지 확인 후
2. 없는것 확인되면 추가
1번 작업 진행 후 2번 실행 전 다른 쓰레드가 끼어들 수 있으므로 안전하지 않다.
- Concurrent Collection (병렬 컬렉션, 자바 5 이후)
Thread-safe 함은 물론이여러 Thread 가 동시에 컬렉션에 접근할 수 있다.
동기화 컬렉션은 하나의 쓰레드가 접근시 다른 쓰레드는 아예 접근 불가능하지만,
병렬 컬렉션은 보관하고 있는 데이터를 여러 부분으로 나눠서 락을 걸어
다른 부분에 접근 중 이라면 여러 쓰레드가 동시 접근도 가능하다.
또한 iteration, put-if-absent, replace, condition-remove 등의 연산을 별도 구현하고 있어
추가적인 동기화도 불필요하다.
ex : java.concurrent 패키지에서 제공하는 Concurrent... 로 시작하는 컬렉션
* CopyOnWrite
http://dogcowking.tistory.com/281
CopyOnWriteArraySet
CopyOnWriteArrayList
* 컬렉션 목록은 다음이 가장 상세함
http://enjoyjava.tistory.com/entry/Java-Collection-Framework-Overview
기타 sort, binarySearch 등 메서드 목록, 예외 목록록
* List
리스트는 일반적으로 ArrayList 를 사용
데이터의 추가, 삭제가 잦다면 LinkedList 가 나음.
하지만 LinkedList 는 메모리 공간을 좀 더 차지함
비슷한 역할을 하는 Vector 는 Java 구버전부터 제공되는 것이라 굳이 사용할 필요 없음
https://www.holaxprogramming.com/2014/02/12/java-list-interface/
ArrayList나 LinkedList 는 동기화를 보장하지 않음 (Vector는 되는데..)
Collections.synchronizedList(List<T> list) 를 이용하여 Thread-safe 하게 바꿀 수 있음.
CopyOnWriteArrayList 를 쓸 수 있지만 add,remove 많다면 성능 떨어짐
(위의 Copy-On-Write 참고)
* Set
중복값 저장 필요 없고 (혹은 제거해야하고), 순서가 없는 데이터는 Set 을 사용
Set 중에는 HashSet을 가장 많이 사용
입력한 순서대로 나오게 하고 싶다면 LinkedHashSet을 사용
값의 정렬이 필요하다면 TreeSet을 이용
이 셋 모두 동기화 제공하지 않으므로, 동기화 위해서는
Collections.synchronizedSet() 이용하거나
ConcurrentSkipListSet 사용
https://stackoverflow.com/questions/6720396/different-types-of-thread-safe-sets-in-java
EnumSet은 Enum 의 원소를 활용하는 Set이다
http://egloos.zum.com/iilii/v/4835182
* Map
일반적으로 HashMap 사용
동기화를 위해선 HashTable 사용할 수 있지만 성능이 떨어지고
좀 더 성능이 좋은 ConcurrentHashMap 사용
또는 Collections.synchronizedMap() 을 사용할 수도 있는데
ConcurrentHashMap 이 낫다 함.
https://stackoverflow.com/questions/1291836/concurrenthashmap-vs-synchronized-hashmap
성능/동기화 외에도 null 허용 등 면에서 약간씩 차이가 있음.
http://www.yunsobi.com/blog/624
HashMap 은 정렬 기능은 없음.
정렬을 하려면 TreeMap 을 사용. 동기화는 제공 안됨.
동기화 위해서는 ConcurrentSkipListMap 을 사용
http://dogcowking.tistory.com/262
EnumMap 은 Key 를 Enum 의 원소로 제한하므로 성능이 좀 더 뛰어남
(동기화는 제공 안됨)
https://seungdols.tistory.com/464
Cache 처럼 임시 보관용 데이터는 GC 에 의해서 내용이 제거될 수 있는 WeakHashMap 이용 가능
http://blog.breakingthat.com/2018/08/26/java-collection-map-weakhashmap/
* Queue
- Java 5 부터 추가
ConcurrentLinkedQueue
LinkedBlockingQueue
ArrayBlockingQueue
PriorityBlockingQueue
DelayQueue
SynchronouseQueue
LinkedTransferQueue
* Deque
- Java 6부터 추가됨.
ArrayDeque
LinkedBlockingDequeue
* Stack
ArrayStack, LinkedStack
*Graph 는 별도로 제공하지 않는다
구현해서 쓰면 되지..
https://stackoverflow.com/questions/1737627/java-how-to-represent-graphs
-- 편집
http://blog.daum.net/dogcowking/168