* 컬렉션 프림워크(Collection Framework)
배열의 단점을 보안하기 위해 자료구조를 바탕으로 객체들을 효율적으로 추가, 삭제, 검색할 수 있도록 java.util 패키지에 컬렉션과 관련된 인터페이스와 클래스들을 포함시켜 놓은 것
(컬렉션 : 객체를 수집해서 저장하는 역할 / 프레임워크 : 사용 방법을 미리 정해 놓은 라이브러리)
인터페이스 분류 | 특징 | 구현 클래스 | |
Collection | List |
순서를 유지하고 저장 중복 저장 가능 |
ArrayList, Vector, LinkedList |
Set |
순서를 유지하지 않고 저장 중복 저장 안 됨 |
HashSet, TreeSet | |
Map |
키와 값의 쌍으로 저장 키는 중복 저장 안 됨 |
HashMap, Hashtable, TreeMap, Properties |
* List 컬렉션
객체를 일렬로 늘어놓은 구조를 가지고 있음
객체를 인덱스로 관리하기 때문에 객체를 저장하면 자동 인덱스가 부여되고 인덱스로 객체를 검색, 삭제할 수 있는 기능을 제공
List 컬렉션은 객체 자체를 저장하는 것이 아니라 객체의 번지를 참조함
동일한 객체에 중복 저장 가능, 이 경우 동일한 범지가 참조됨
null도 저장이 가능, 이 경우 해당 인덱스는 객체를 참조하지 않음
List 컬렉션에는 ArrayList, Vector, LinkedList 등이 있으며, 다음은 List 컬렉션에서 공통적으로 사용 가능한 List 인터페이스의 메소드들이다. (인덱스로 객체를 관리하기 때문에 인덱스를 매개값으로 갖는 메소드가 많음)
기능 | 메소드 | 설명 |
객체 추가 |
boolean add(E e) | 주어진 객체를 맨 끝에 추가 |
void add(int index, E element) | 주어진 인덱스에 객체를 추가 | |
E set(int index, E element) | 주어진 인덱스에 저장된 객체를 주어진 객체로 바꿈 | |
객체 검색 | boolean contains(Object o) | 주어진 객체가 저장되어 있는지 여부 |
E get(int index) | 주어진 인덱스에 저장된 객체를 리턴 | |
boolean isEmpty() | 컬렉션이 비어 있는지 조사 | |
int size() | 저장되어 있는 전체 객체 수를 리턴 | |
객체 삭제 | void clear() | 저장된 모든 객체를 삭제 |
E remove(int index) | 주어진 인덱스에 저장된 객체를 삭제 | |
boolean remove(Object o) | 주어진 객체를 삭제 |
1) ArrayList
ArrayList에 객체를 추가하면 객체가 인덱스로 관뢰됨
일반 배열과 인덱스로 객체를 관리한다는 점에서는 유사
배열은 생성할 때 크기가 고정되고 사용 중 크기를 변경할 수 없지만, ArrayList는 저장용량(capacity)을 초과한 개겣들이 들어오면 자동적으로 저장 용량이 늘어남
2) Vector
ArrayList와 동일한 내부 구조를 가지고 있음
Vector를 생성하기 위해서는 저장할 객체 타입을 타입 파라미터로 표기하고 기본 생성자를 호출
ArrayList와 다른 점은 Vector는 동기화된(synchronized) 메소드로 구성되어 있기 때문에 멀티 스레드가 동시에 이 메소드들을 실행할 수 없고, 하나의 스레드가 실행을 완료해야만 다른 스레드를 실행할 수 있음
멀티 스레드 환경에서 안전하게 객체를 추가, 삭제할 수 있음 -> 스레드가 안전(Thread Safe)하다
3) LinkedList
List 구현 클래스이므로 ArrayList와 사용 방법은 똑같지만 내부 구조는 완전 다름
ArrayList는 내부 배열에 객체를 저장해서 인덱스로 관리하지만, LinkedList는 인접 참조 링크를 해서 체인처럼 관리
특정 인덱스의 객체를 제거하면 앞뒤 링크만 변경되고 나머지 링크는 변경되지 않음(삽입도 마찬가지)
* Set 컬렉션
List 컬렉션은 저장 순서를 유지하지만, Set 컬렉션은 저장 순서가 유지되지 않음
객체를 중복해서 저장할 수 없고 하나의 null만 저장 가능 (수학의 집합과 유사)
들어갈(저장할) 때의 순서와 나올(찾을) 때의 순서가 다를 수 있음
Set 컬렉션에는 HashSet, LinkedHashSet, TreeSet 등이 있으며, 다음은 Set 컬렉션에서 공통적으로 사용 가능한 Set 인터페이스의 메소드들이다.
기능 | 메소드 | 설명 |
객체 추가 | boolean add(E e) | 주어진 객체를 저장, 성공적으로 저장되면 true 중복 객체면 false 리턴 |
객체 검색 | boolean contains(Object o) | 주어진 객체가 저장되어 있는지 여부 |
boolean isEmpty() | 컬렉션이 비어 있는지 조사 | |
Iterator<E> iterator() | 저장된 객체를 한 번씩 가져오는 반복자 리턴 | |
int size() | 저장되어 있는 전체 객체 수 리턴 | |
객체 삭제 | void clear() | 저장된 모든 객체를 삭제 |
boolean remove(Object o) | 주어진 객체를 삭제 |
* Map 컬렉션
Map 컬렉션은 키(key)와 값(value)으로 구성된 Entry 객체를 저장하는 구조를 가지고 있음(키와 값은 모두 객체)
키는 중복 저장될 수 없지만 값은 중복 저장될 수 있음
만약 기존에 저장된 키와 동일한 키로 값을 저장하면 기존의 값은 없어지고 새로운 값으로 대치됨
Map 컬렉션에는 HashMap, Hashtable, LinkedHashMap, Properties, TreeMap 등이 있으며, 다음은 Map 컬렉션에서 공통적으로 사용 가능한 메소드들이다.
기능 | 메소드 | 설명 |
객체 추가 | V put(K key, V value) | 주어진 키로 값을 저장, 새로운 키일 경우 null, 동일한 키가 있을 경우 값을 대체하고 이전 값 리턴 |
객체 검색 | boolean containsKey(Object key) | 주어진 키가 있는지 여부 |
boolean containsValue(Object value) | 주어진 값이 있는지 여부 | |
Set<Map.Entry<K.V>> entrySet() | 키와 값의 쌍으로 구성된 모든 Map.Entry 객체를 Set 담아서 리턴 | |
V get(Object key) | 주어진 키가 있는 값을 리턴 | |
boolean isEmpty() | 컬렉션이 비어 있는지 여부 | |
Set<K> keySet() | 모든 키를 Set 객체에 담아서 리턴 | |
int size() | 저장된 키의 총 수를 리턴 | |
Collection<V> values() | 저장된 모든 값을 Collection에 담아서 리턴 | |
객체 삭제 | viod clear() | 모든 Map.Entry(키와 값)를 삭제 |
V remove(Object key) | 주어진 키와 일치하는 Map.Entry를 삭제하고 값을 리턴 |
* 검색 기능을 강화시킨 컬렉션
컬렉션 프레임워크는 검색 기능을 강화시킨 TreeSet과 TreeMap을 제공
이 컬렉션들은 이진트리(binary tree)를 이용해서 계층적 구조를 가지면서 객체를 저장
1) Tree Set
이진트리를 기반으로한 Set 컬렉션
하나의 노드는 노드값인 value와 왼쪽과 오른쪽 자식 노드를 참조하기 위한 두 개의 변수로 구성됨
TreeSet에 객체를 저장하면 자동으로 정렬되는데, 부모값과 비교해 낮은 것은 왼쪽 자식 노드, 높은 것은 오른쪽 자식 노드에 저장
2) Tree Map
이진트리를 기반으로 한 Map 컬렉션
TreeSet과의 차이점은 키와 값이 저장된 Map.Entry를 저장한다는 점
TreeMap에 객체를 저장하면 자동으로 정렬되는데, 부모 키값과 비교해 키 값이 낮은 것은 왼쪽 자식 노드, 높은 것은 오른쪽 자식 노드에 Map.Entry 객체를 저장
* LIFO와 FIFO 컬렉션
LIFO(Last In First Out)은 나중에 넣은 객체가 먼저 빠져나가는 자료구조
FIFO(First In First Out)은 먼저 넣은 객체가 먼저 빠져나가는 자료구조
컬렉션 프레임워크에는 LIFO 자료구조를 제공하는 스택 클래스와 FIFO 자료구조를 제공하는 큐 인터페이스를 제공
스택을 응요한 대표적인 예가 JVM 스택 메모리임(스택 메모리에 저장된 변수는 나중에 저장된 것부터 제거)
큐를 응용한 대표적인 예가 스레드풀(ExecutorService)의 작업 큐임(먼저 들어온 작업부터 처리)
* 동기화된 컬렉션
컬렉션 프레임워크의 대부분의 클래스들은 싱글 스레드 환경에서 사용할 수 있도록 설계되었음
-> 여러 스레드가 동시에 컬렉션에 접근한다면 의도하지 않게 요소가 변경될 수 있는 불안전한 상태가 됨
Vector와 Hashtable은 동기화된 메소드로 구성되어 있기 때문에 멀티 스레드 환경에서 안전하게 요소를 처리 가능
ArrayList, HashSet, HashMap은 동기화된 메소드로 구성되어 있지 않아 멀티 스레드 환경에서 안전하지 않음
이런 경우를 대비해서 컬렉션 프레임워크는 비동기화된 메소드를 동기화된 메소드로 래핑하는 메소드를 제공
(매개값으로 비동기화된 컬렉션을 대입하면 동기화된 컬렉션을 리턴)
리턴 타입 | 메소드(매개 변수) | 설명 |
List<T> | synchronizedList(List<T> list) | List를 동기화된 List로 리턴 |
Map<K, V> | synchronizedMap(Map<K, V> m) | Map을 동기화된 Map으로 리턴 |
Set<T> | synchronizedSet(Set<T> s) | Set을 동기화된 Set으로 리턴 |
* 병렬 처리를 위한 컬렉션
동기화된 컬렉션은 멀티 스레드 환경에서 하나의 스레드가 요소를 안전하게 처리하도록 도와주지만, 전체 요소를 빠르게 처리하지는 못함
하나의 스레드가 요소를 처리할 때 전체 잠금이 발생하여 다른 스레드는 대기 상태가 됨
-> 멀티 스레드가 병렬적으로 컬렉션의 요소들을 처리할 수 없음
자바는 멀티 스레드가 컬렉션의 요소를 병렬적으로 처리할 수 있도록 컬렉션 제공
-> java.util.concurrrent 패키지의 ConcurrentHashMap과 ConcurrentLinkedQueue
ConcurrentHashMap : 스레드에 안전하면서도 멀티 스레드가 요소를 병렬적으로 처리할 수 있음(부분(segment) 잠금을 사용하기 때문)
ConcurrentLinkedQueue : 락-프리(lock-free) 알고리즘을 구현한 컬렉션. 여러 개의 스레드가 동시에 접근할 경우, 잠금을 사용하지 않고도 최소한 하나의 스레드가 안전하게 요소를 저장하거나 얻도록 해줌
'Programming Language > Java' 카테고리의 다른 글
이것이 자바다 16 (0) | 2019.12.26 |
---|---|
이것이 자바다 14 (0) | 2019.08.01 |
이것이 자바다 13 (0) | 2019.07.26 |
이것이 자바다 12 (0) | 2019.07.23 |
이것이 자바다 10 (0) | 2019.07.08 |