Arrays가 배열과 관련된 메서드를 제공하는 것 처럼, Collections는 컬렉션과 관련된 메서드를 제공한다. fill()
(컬렉션 채우기), copy()
(복사), sort()
(정렬), binarySearch()
(검색) 등의 메서드는 두 클래스에 모두 포함되어 있으며 같은 기능을 한다.
컬렉션 프레임워크의 대부분의 클래스들은 싱글 스레드 환경에서 사용할 수 있도록 설계되었다. 그렇기 때문에 여러 쓰레드가 동시에 컬렉션에 접근한다면 의도하지 않게 요소가 변경될 수 있는 불안전한 상태가 된다.
멀티 쓰레드(multi-thread) 프로그래밍에서는 하나의 객체를 여러 쓰레드가 동시에 접근할 수 있기 때문에 데이터의 일관성(consistency)을 유지하기 위해서는 공유되는 객체에 동기화(synchronization)가 필요하다.
Vector
와 Hashtable
): 자체적으로 동기화 처리가 되어있음.ArrayList
와 HashMap
)은 필요한 경우에만 동기화 처리가 가능하도록 변경되었다.Collections 클래스에서는 다음과 같은 동기화 메서드를 제공하므로, 동기화가 필요할 때 해당하는 것을 사용하면 된다.
static Colelction synchronizedCollection(Collection c)
static List synchronizedList(List list)
static Set synchronizedSet(Set s)
static Map synchronizedMap(Map m)
static SortedSet synchronizedSortedSet(SortedSet s)
static SortedMap synchronizedSortedMap(SortedMap m)
이들을 사용하는 것은 아래와 같이 사용하면 된다.
List syncList = Collections.synchronizedList(new ArrayList(...));
Collection 동기화된컬렉션 = Collections.synchronizedXXX(동기화 되지 않은 컬렉션);
final int
와 같이 변수를 상수화시켜 변경이 불가능하도록 해야하는 경우가 있다. 컬렉션 역시 저장된 데이터를 보호하기 위해 데이터가 변경할 수 없게, 즉 읽기 전용으로 만들어야 할 때가 있다.
static Collection unmodifiableCollection(Collection c)
static List unmodifiableList(List list)
static Set unmodifiableSet(Set s)
static Map unmodifiableMap(Map m)
static NavigableSet unmodifiableNavigableSet(NavigableSet s)
static SortedSet unmodifiableSortedSet(SortedSet s)
static NavigableMap unmodifiableNavigableMap(NavigableMap m)
static SortedMap unmodifiableSortedMap(SortedMap m)
static List singletonList(Object o)
static Set singleton(Object o) // singleSet이 아님에 주의
stiatc Map singletonMap(Object key, Object value)
static Collection checkedCollection(Collection c, Class type)
static List checkedList(List list, Class type)
static Set checkedSet(Set s, Class type)
static Map checkedMap(Map m, Class keyType, Class valueType)
static Queue checkedQueue(Queue queue, Class type)
static NavigableSet checkedNavigableSet(NavigableSet s, Class type)
static SortedSet checkedSortedSet(SortedSet s, Class type)
static NavigableMap checkedNavigableMap(NavigableMap m, Class keyType, Class valueType)
static SortedMap checkedSortedMap(SortedMap m, Class keyType, Class valueType)
List list = new ArrayList();
List checedList = checkedList(list, String.class); // String만 저장가능
checkedList.add("abc");
checkedList.add(new Integer(3)); // 에러. ClassCastException 발생
지네릭스를 사용하면 되지 않나요?
컬렉션에 저장할 요소의 타입을 제한하는 것은 지네릭스(generics)로 간단히 처리할 수 있다. 그럼에도 불구하고 해당 메서드들을 제공하는 이유는 호환성 때문이다. 지네릭스는 JDK 1.5부터 도입된 기능으로 JDK 1.5 이전에 작성된 코드를 사용할 때 이 메서드들이 필요할 수 있다.
동기화된(synchronized) 컬렉션은 멀티 스레드 환경에서 하나의 스레드가 요소를 안전하게 처리하도록 도와주지만, 전체 요소를 빠르게 처리하지는 못한다. 하나의 요소를 처리할 때 전체 잠금이 발생하여 다른 스레드는 대기 상태가 된다. 그렇기 때문에 멀티 스레드가 병렬적으로 컬렉션의 요소들을 처리할수 없다.
자바는 멀티 스레드가 컬렉션의 요소를 병렬적으로 처리할 수 있도록 특별한 컬렉션을 제공하고 있다.
java.util.concurrent
패키지의 ConcurrentHashMap
과 ConcrrentLinkedQueue
이다. ConcurrentHashMap
은 Map 구현 클래스이고, ConcurrentLinkedQueue
는 Quene 구현 클래스이다.ConcurrentHashMap
: 스레드가 안전하면서도 멀티 스레드가 요소를 병렬적으로 처리할 수 있다.
다음은 ConcurrentHashMap
객체를 생성하는 코드이다. 다른 Map 구현 객체와 마찬가지로 Map 인터페이스의 메서드를 호출하면 된다.
Map<K, V> map = new ConcurrentHashMap<K, V>();
ConcurrentLinkedQueue
: 락-프리(lock-free) 알고리즘을 구현한 컬렉션.
다음은 ConcurrentLinkedQueue
를 생성하는 코드이다.
Queue<E> queue = new ConcurrentLinkedQueue<E>();