Java : Collection
Collection
Collection
이란 어떠한 자료구조(Queue, Stack 등등…)를 구현한 클래스를 의미합니다.JCF(Java Collections Framework)
는 컬렉션과 이를 구현하는 클래스를 정의하는Interface(공통된 메소드를 모아놓은)
를 제공합니다.Collection Interface
는List, Set, Queue
크게 3가지 상위Interface
로 분류할 수 있습니다.Map
의 경우Collection Interface
를 상속받고 있진 않지만Collection
으로 분류됩니다.
Collection Interface특징
자료 구조 성능 요약
밑의 내용에서 시간 복잡도는 Average 시간 복잡도
를 말합니다.
List Interface
- 순서가 있는 데이터의 집합
- 색인을 사용하여 특정 위치에 요소를 삽입하거나 접근할 수 있으며 데이터의 중복, Null값을 허용합니다.
List Interface의 메소드
ArrayList
-
ArrayList
는 RandomAccess 마커 Interface를 상속하여 구현됩니다. -
상당히 빠르고 크기를 마음대로 조절할 수 있는 배열
- 객체들이 추가되어
저장 용량(capacity)
을 초과한다면 자동으로저장 용량(capacity)
이 늘어난다는 특징을 가지고 있습니다.
- 객체들이 추가되어
-
초기에 생성하면 10개의 객체를 저장할 수 있는
List
가 선언됩니다. -
단방향 포인터 구조로 각 데이터에 대한 인덱스를 가지고 있어 조회 기능에 성능이 뛰어납니다.
Access
의 시간 복잡도가O(1)
-
인덱스가 순차적으로 존재해야하는 구조 특성상, 한 원소를 삽입/삭제 시 배열의 나머지 원소들의 인덱스 참조값을 수정해야 합니다.
- 그림에서 처럼 6개의 인덱스를 가지던 배열에서 3번 원소를 삭제하면, 4, 5, 6번째 원소는 각각 3, 4, 5번으로 수정되어야 하므로 한 칸씩 당겨집니다.
-
Insertion, Deletion
의 시간 복잡도가O(n)
-
특정한 값을 찾기 위해서는 처음 부터 값을 순서대로 찾아야 합니다.
Search
의 시간 복잡도가O(n)
List<E> list = new ArrayList<E>(); // E에는 어떤 객체 타입이던 올 수 있다.
Vector
- 과거에 대용량 처리를 위해 사용했습니다.
- 내부에서 자동으로 동기화처리가 일어나 비교적 성능이 좋지 않고 무거워 잘 쓰이지 않습니다.
ArrayList
의 시간복잡도와 같습니다.Access
의 시간 복잡도O(1)
,Insertion, Deletion, Search
의 시간 복잡도가O(n)
List<E> list = new Vector<E>();
Stack
후입선출 (LIFO : Last In First Out)
으로 이루어진 자료구조Interface
입니다.Java
의Stack
은Vector
를 상속받고 있습니다.Vector
의 뒤에서만 데이터가 오고 가기 때문에Insertion, Deletion
의 시간 복잡도가O(1)
Vector
를 사용하기 때문에Search
의 시간 복잡도가O(n)
,Access
의 시간 복잡도가O(1)
Access
의 경우에는 어떤 자료구조로Stack
을 구현하였는지에 따라 달라지게 되는데, Java의 경우 Vector를 이용하기 때문에 O(1)이 될 수 있습니다. (LinkedList
로 구현할 경우O(n)
)
Stack<E> stack = new Stack<E>();
LinkedList
-
LinkedList는 List와 Deque를 구현한 class입니다.
- 양방향 포인터 구조로 인접 참조를 링크해서 체인처럼 관리합니다.
- 데이터의 삽입, 삭제가 빈번할 경우 데이터의 위치정보만 수정하면 되기에 유용합니다. (빠른 성능을 보장)
- 스택, 큐, 양방향 큐 등을 만들기 위한 용도로 쓰입니다.
- 초기에 생성하면 어떠한 링크도 만들어지지 않기 때문에 내부적으로 비어있습니다.
랜덤 접근(Random Access)
이 아닌순차 접근(Sequential Access)
방식을 따르므로ArrayList
처럼 바로 해당 데이터로 접근할 수가 없습니다.Access
의 시간 복잡도가O(n)
- 노드값이외에 앞 뒤 포인터 값을 저장하고 있는 자료구조이므로, 삭제와 삽입시 해당 노드 앞 뒤의 포인터 값만 수정해주면 추가/삭제가 완료됩니다.
- 삭제, 추가할 위치를 알고 있다는 가정하의 효율값이고 모른다면 검색이 필요하므로 시간 복잡도는
O(n)
이 됩니다. - 하지만 보통 알고 있다고 가정하기 때문에
Insertion, Deletion
의 시간 복잡도가O(1)
- 삭제, 추가할 위치를 알고 있다는 가정하의 효율값이고 모른다면 검색이 필요하므로 시간 복잡도는
ArrayList
와 마찬가지로 특정한 값을 찾기 위해서는 처음 부터 값을 순서대로 찾아야 합니다.Search
의 시간 복잡도가O(n)
List<E> list = new LinkedList<E>();
LinkedList의 종류
Java
의 LinkedList
를 말하는 것이 아니고, 자료구조 상의 LinkedList
를 말합니다. (자바의 LinkedList
는 이중 연결 리스트(Doubly Linked List)
입니다.)
단일 연결 리스트(Singly Linked List)
- 각 노드가 다음 노드에 대해서만 참조하는 가장 단순한 형태의
LinkedList
입니다. - 일반적으로 큐를 구현할 때 사용됩니다.
- Head 노드를 잃어버려 참조하지 못하는 경우 데이터 전체를 사용 못하게 되는 단점이 있습니다.
- FAT 파일 시스템이 단일 연결 리스트로 파일 청크(동적 메모리로 할당되는 영역)를 연결합니다.
이중 연결 리스트(Doubly Linked List)
- 각 노드가 이전 노드, 다음 노드에 대해서 참조하는 형태의
LinkedList
입니다. - 삭제가 간편하며 단일 연결 리스트에 비해 데이터 손상에 강하지만, 관리할 참조가 2개이기 때문에 삽입이나 정렬의 경우 작업량이 더 많아집니다.
원형 연결 리스트(Circular Linked List)
- 연결 리스트에서 마지막 요소가 첫번째 요소를 참조합니다.
- 스트림 버퍼의 구현에 많이 사용됩니다.
성능 비교
Access | Search | Insertion | Deletion | |
---|---|---|---|---|
ArrayList | O(1) | O(n) | O(n) | O(n) |
Vector | O(1) | O(n) | O(n) | O(n) |
Stack | O(1) | O(n) | O(1) | O(1) |
LinkedList | O(n) | O(n) | O(1) | O(1) |
표를 보면, 데이터 조회가 자주 이루어질 때 ArrayList
를 사용하는 것이 유리하고, 데이터의 삽입, 삭제가 빈번히 일어날 때 LinkedList
를 사용하는 것이 유리한 것을 알 수 있습니다.
메모리 점유율 면에서는 ArrayList
가 LinkedList
보다 더 효율적입니다. ArrayList
는 실제 데이터와 인덱스만 저장하는 반면, LinkedList
의 각각의 노드는 데이터와 앞 뒤의 원소의 포인터값까지 저장함으로써 더 많은 메모리를 점유하기 때문입니다.
Queue 와 Deque Interface
Java
에서는 Deque
는 Queue
를 상속받는 sub interface
이지만 자료구조에서 Queue
와 Deque
을 구분하기 때문에 나누어 설명하겠습니다.
Queue Interface
-
선입선출 (FIFO : First In First Out)
으로 이루어진 자료구조Interface
입니다. -
가장 앞쪽에 있는 위치를
head(헤드)
라고 부르고, 가장 후위(뒤)에 있는 위치를tail(꼬리)
라고 부릅니다.
Deque (Double ended Queue) Interface
-
Queue
를 상속받고 있는Interface
입니다. Queue
는 한쪽 방향으로만(단방향) 삽입 삭제가 가능하지만,Deque(Double ended Queue)
는 양쪽에서 삽입삭제가 가능한 자료구조 입니다.- head에서도 접근 가능하며, tail에서도 접근 가능한 양방향 큐
- 양방향에서 접근할 수 있기 때문에,
Stack
처럼 사용할 수도 있고,Queue
처럼 사용할 수도 있습니다. Deque
의 주의할 점은 List처럼 index 관련 기능을 수행하지 않기때문에 index로 요소에 접근이 불가능하다는 것입니다.
Queue와 Deque Interface의 메소드
LinkedList
- LinkedList는 List와 Deque를 구현한 interface 입니다.
-
Deque를 구현하고 있기 때문에 Deque로도 선언할 수 있고, Deque는 Queue를 상속받기 때문에 Queue로도 선언할 수 있습니다.
- 일반적으로 말하는
Queue
를Java
에서는LinkedList
로 생성하면 됩니다.LinkedList
를 사용하기 때문에Search
의 시간 복잡도가O(n)
,Insertion, Deletion
의 시간 복잡도가O(1)
.Access
의 시간 복잡도가O(n)
-> 원하는 위치에Access
하기 위해Queue
에서 하나씩 빼야하기 때문
Queue<E> queue = new LinkedList<E>();
Deque<E> deque = new LinkedList<E>();
PriorityQueue
PriorityQueue
는 Queue에서 데이터 우선순위에 기반하여 우선순위가 높은 데이터가 먼저 나오는 원리입니다.- 따로 정렬방식을 지정하지 않는다면 낮은 숫자가 높은 우선순위를 갖습니다. (오름차순)
PriorityQueue
는Heap
을 이용하여 구현하는 것이 일반적입니다.- 삽입과 삭제시, 자동으로 정렬(기본 오름차순)하기 때문에 저장시간이 다소 오래 걸립니다.
- 삽입, 삭제 시,
Heap
구조를 이용해 정렬하기 때문에Insertion, Deletion
의 시간 복잡도가O(log(n))
PriorityQueue
자체가 높은 우선순위를 찾는 것이 목적이기 때문에Search
의 시간 복잡도는O(1)
,Access
의 시간 복잡도는O(n)
(몇 번째로 높은지)
- 삽입, 삭제 시,
- 주의할 점은 처음에 위치한 데이터가 아닌, 그 밖의 데이터들이 완벽하게 정렬된 것이 아니라는 것입니다. (
약한 힙(weak heap)
)- 삽입, 삭제 시에 다시 정렬함으로써, 데이터들 중 우선순위가 가장 높은 데이터를 제일 처음에 위치하게 만드는 것에만 초점을 둡니다.
- 즉, 모든 데이터들이 완벽하게 정렬되지 않을 수 있습니다.
- 사용자가 정의한 객체를 타입으로 쓸 경우 반드시 Comparator 또는 Comparable을 통해 정렬 방식을 구현해주어야 합니다.
PriorityQueue<E> priorityQueue = new PriorityQueue<E>();
Comparable 과 Comparator
PriorityQueue
의 정렬방식을 지정할 때나, 밑에서 나올 내용인TreeSet
의 객체,TreeMap
의 키의 크기를 비교해 트리구조를 구성해야 할 때,java.lang.Comparable Interface
를Implements
하여 구현해야 합니다.
Comparable
- 기본적인 Wrraper Class들은 Comparable Interface가 구현되어 있어
PriorityQueue
,TreeSet
,TreeMap
을 사용할 수 있습니다. - ArrayList 등의 자료구조의 Collection.sort()함수를 사용할때도 Comparable을 이용해 compareTo()메소드만 재정의하게되면 쉽게 Collection 프레임워크의 자료구조들을 정렬하여 사용할 수 있습니다.
리턴 타입 | 메소드 | 설명 |
---|---|---|
int | compareTo(Object o) | 주어진 객체와 같으면 0을 리턴 주어진 객체보다 작으면 음수를 리턴 주어진 객체보다 크면 양수를 리턴 |
Comparator
- PriorityQueue, TreeSet, TreeMap이 Comparable을 구현하고 있지 않을 경우에는 저장하는 순간 ClassCastException이 발생합니다.
- Comparable 구현체를 구현하는 방법 외에 Comparator Interface를 이용해 정렬할 수 있습니다.
// DescendingComparator, AscendingComparator는 Comparator Interface를 구현한 객체입니다.
TreeSet<E> treeSet = new TreeSet<E>(new AscendingComparator());
TreeMap<K, V> treeMap = new TreeMap<K, V>(new DescendingComparator());
PriorityQueue<E> priorityQueue = new PriorityQueue<E>(new DescendingComparator());
- 정렬자는
Comparator Interface
를 구현한 객체를 말하는데,Comparator Interface
는 다음과 같은 메소드가 정의되어 있습니다.
리턴 타입 | 메소드 | 설명 |
---|---|---|
int | compareTo(Obect o1, Object o2) | o1과 o2가 동등하다면 0을 리턴 o1이 o2보다 앞에 오게하면 음수를 리턴 o1이 o2보다 뒤에 오게하면 양수를 리턴 |
Comparable / Comparator에 대한 더 자세한 설명
ArrayDeque
- ArrayDeque는 배열(Array)과 두개의 포인터(head와 tail을 가리키는 포인터)를 사용해 Deque를 구현한 interface입니다.
Null
은 저장되지 않습니다.ArrayDeque
로Stack
과Queue
를 사용할 시, 기존의 Stack과 LinkedList보다 빠릅니다.- 앞, 뒤에서의
Insertion, Deletion
의 시간 복잡도가O(1)
,Search
는 하나씩 빼면서 찾아야 하기 때문에O(n)
Java
의ArrayDeque
는임의 접근(Access)
을 지원하지 않기 때문에 하나씩 빼가면서 접근(O(n)
)해야 하지만, 직접 구현할 시배열(Array)
을 사용하기 때문에Access
의 시간 복잡도가O(1)
이 될 수 있습니다.
성능 비교
Access | Search | Insertion | Deletion | |
---|---|---|---|---|
LinkedList | O(n) | O(n) | O(1) | O(1) |
PriorityQueue | O(n) | O(1) | O(log(n)) | O(log(n)) |
ArrayDeque | O(n) or O(1) | O(n) | O(1) | O(1) |
LinkedList | PriorityQueue | ArrayDeque | |
---|---|---|---|
implements | List, Deque | Queue | Deque |
내부로직 | LinkedList | Heap | Array |
순서 | 선입선출 (FIFO : First In First Out) | Comporator 가 정의되지 않을 경우 오름차순에 의해 자동 정렬 |
Stack(LIFO) 으로도 사용할 수 있고 Queue(FIFO) 로도 사용할 수 있음 |
성능 | ArrayDeque보다 느립니다. | 삽입과 삭제 후 재정렬해야하므로 가장 느립니다. | 배열(Array)과 두개의 포인터를 사용하기 때문에 가장 빠릅니다. |
Null Value | Null 허용 | 허용하지 않음 | 허용하지 않음 |
사용 용도 | 일반적으로 사용하는 Queue | 우선순위를 이용해야 하는 경우 | Queue나 Stack을 더 빠르게 사용하고 싶을 때 |
Set Interface
- Collection Interface를 상속합니다.
- 순서를 유지하지 않는 데이터의 집합
- 인덱스로 객체를 검색해서 가져오는 메소드가 없습니다.
- 대신 전체 객체를 대상으로 한번씩 반복해서 가져오는 반복자(
Iterator
)를 제공합니다.
- 데이터의 중복을 허용하지 않습니다.
Set Interface의 메소드
HashSet
- 순서를 예측할 수 없습니다.
- 인덱스를 사용하지 않고 해쉬함수(
hashCode()
)를 이용해 해쉬코드를 만들어 객체를 판별합니다.- 인덱스를 사용하지 않기 때문에
Acces
는 불가능합니다.(N/A
)
- 인덱스를 사용하지 않기 때문에
- 대부분의 객체들이 고유한 해쉬코드(중복될 수도 있습니다.)를 가지게 되기 때문에 해쉬코드를 이용해 배열의 인덱스처럼 바로 접근할 수 있습니다.
Search, Insertion, Deletion
의 시간 복잡도가O(1)
HashSet
이 판단하는 동일한 객체란 꼭 같은 인스턴스를 뜻하지 않습니다.hashCode()
와equals()
를 재정의해서 동일한 리턴 값을 가지면 동등한 객체로 간주합니다.
Set<E> set = new HashSet<E>();
해쉬 함수(Hash Function)
해쉬 함수란, 어떤 가변 값의 key를 input으로 해쉬함수에 넣으면 output으로 고정된 hash값이 나오게 하는 것입니다. 예를 들어, 내부 로직이 f(x)= x % 10
인 해쉬함수가 있다고 가정했을 때 84, 123, 27의 해쉬값은 각각 4, 3, 7이 되고, 이 해쉬값에 따른 위치에 저장합니다. 즉, 123은 3에, 84는 4에, 27은 7에 저장됩니다.
그런데, input은 거의 무한대의 가변값인데 반해 hash는 고정값을 가지므로, 중복 hash값이 발생할 수 있습니다. 가령 위의 해쉬함수에 223이라는 값을 input으로 넣어도 123을 넣었을 때와 같은 hash값(3)을 얻게 됩니다. 이러한 현상을 해쉬 충돌(hash collision)
이라고 하는데, 이 때에는 Java에서는 동일한 해쉬값에 대해 LinkedList로 저장됩니다. 해쉬 함수를 잘못 설계하게 되면 하나의 해쉬코드에 대량의 객체가 들어가 있을 수 있기 때문에 Worst 시간 복잡도가 O(n)
인 것입니다.
LinkedHashSet
- 추가된 순서 또는 가장 최근에 접근한 순서대로 접근 가능한 HashSet 입니다.
- HashSet과 시간복잡도는 동일합니다.
Search, Insertion, Deletion
의 시간 복잡도가O(1)
,Acces
는 (N/A
).
- 데이터에 앞 뒤 포인터 정보를 포함하여 저장하는 선형구조 입니다.
- 저장되는 순서를 보장하지만, 점유하는 메모리가 더 많습니다.
TreeSet
- 이진 트리 구조에 자료를 저장합니다.
- 트리 구조를 이용하기 때문에
Search, Insertion, Deletion
의 시간 복잡도가O(log(n))
,Acces
는N/A
- 트리 구조를 이용하기 때문에
- 하나의 노드는 노드 값인 value와 왼쪽과 오른쪽 자식노드를 참조하기 위한 두 개의 변수로 구성됩니다.
- 객체를 저장하면 자동으로 정렬됩니다. (기본 오름차순)
- 정렬된 순서대로 보관하며 Comparable나 Comparator를 이용해 정렬방법을 지정할 수 있습니다.
TreeSet<E> treeSet = new TreeSet<E>();
이진 트리 구조
- 이진 트리는 여러개의 노드가 트리형태로 이루어져 연결된 구조입니다.
- 검색 기능을 강화시킨 구조입니다.
- 루트 노드라고 불리는 하나의 노드에서부터 시작해, 각 노드에 최대 2개의 노드를 연결할 수 있는 구조를 가집니다.
- 부모 노드의 값보다 작은 노드는 왼쪽에 위치 시키고 큰 노드는 오른쪽에 위치시킵니다.
- 숫자가 아닌 문자가 저장할경우에는 문자의 유니코드 값으로 비교합니다.
- 예를 들어 6,3,9,2,5의 순서로 값을 저장하면 다음과 같은 순서로 진행됩니다.
- 아래와 같이 값들이 정렬되어 있어 그룹핑이 쉽기 때문에 범위 검색을 쉽게할 수 있습니다.
성능 비교
Access | Search | Insertion | Deletion | |
---|---|---|---|---|
HashSet | N/A | O(1) | O(1) | O(1) |
LinkedHashSet | N/A | O(1) | O(1) | O(1) |
TreeSet | N/A | O(log(n)) | O(log(n)) | O(log(n)) |
HashSet과 LinkedHashSet은 Hash값으로 호출/삭제/삽입을 하므로 모든 연산에 있어 O(1)의 시간 효율성을 가집니다.
TreeSet은 이진 탐색 트리를 사용하므로, 검색/삽입/삭제의 시간 효율성은 log(n)을 가지게 됩니다.
HashSet | LinkedHashSet | TreeSet | |
---|---|---|---|
내부로직 | Hashing | Hashing | 이진 탐색 트리(BST : Binary Search Tree) |
순서 | 유지되지 않음 | 삽입순서 유지 | Comporator 가 정의되지 않을 경우 오름차순에 의해 자동 정렬 |
성능 | 가장 좋음 | 삽입순서를 유지하기 위하여 포인터값을 저장하므로 HashSet 보다 약간 느립니다. | 삽입과 삭제 후 재정렬해야하므로 셋 중에서 가장 느립니다. |
Null Value | 최대 한 개의 Null 허용 | 최대 한 개의 Null 허용 | 허용하지 않음 |
사용 용도 | 순서를 유지할 필요가 없다면 일반적으로 권장됩니다. | 삽입순서를 유지하고 싶다면 선택 | Comparator 에 의해 원소들을 정렬하고 싶다면 선택 |
Map Interface
키(Key), 값(Value)
의 쌍으로 이루어진 데이터의 집합- 순서는 유지되지 않으며 키(Key)의 중복을 허용하지 않으나 값(Value)의 중복은 허용합니다.
- 맵 안에 데이터를 하나하나 얻어 내는 방법
Map
의(Key, Value)
로 이루어진 구조가 다른 자료구조들과는 다르기 때문에Collection Interface
를 상속받고 있진 않지만Collection
으로 분류됩니다.
HashMap
Map Interface
를 구현하기 위해해쉬코드
를 사용한 classSearch, Insertion, Deletion
의 시간 복잡도가O(1)
,Acces
는N/A
- Key의 중복과 순서가 허용되지 않습니다.
- 키와 값으로 nll값이 올 수 있습니다.
- HashSet과 마찬가지로 hashCode와 equals를 재정의해서 동일한 리턴 값을 가지면 동등한 객체로 간주합니다.
Map<K, V> map = new HashMap<K, V>();
Hashtable
- HashMap과 동일한 내부구조를 가집니다.
Search, Insertion, Deletion
의 시간 복잡도가O(1)
,Acces
는N/A
- HashMap 보다는 느리지만 동기화 지원
- 동기화된 메소드로 구성되어 있기때문에 멀티스레드가 동시에 이 메소드들을 실행할 수 없습니다.
- 하나의 스레드가 실행을 완료해야 다른 스레드가 실행할 수 있습니다.
- 키와 값으로 null값이 허용되지 않습니다.
Map<K, V> map = new Hashtable<K, V>();
LinkedHashMap
- 기본적으로 HashMap을 상속받아 HashMap과 매우 흡사합니다.
Search, Insertion, Deletion
의 시간 복잡도가O(1)
,Acces
는N/A
- 삽입순서를 유지하기 위하여 포인터값을 저장하므로 HashMap 보다 약간 느립니다.
- Map에 있는 엔트리들의 연결 리스트가 유지되므로 입력한 순서대로 반복 가능합니다.
Map<K, V> map = new LinkedHashMap<K, V>();
TreeMap
- 키와 값의 쌍으로 이루어진 데이터
MapEntry
를 저장 - 객체를 저장하면 기본적으로 부모 키값과 비교해서 키값이 낮은 것은 왼쪽, 높은 것은 오른쪽에 자동으로 정렬됩니다.
- 트리 구조를 이용하기 때문에
Search, Insertion, Deletion
의 시간 복잡도가O(log(n))
,Acces
는N/A
- 트리 구조를 이용하기 때문에
- 정렬된 순서대로 키(Key)와 값(Value)을 저장하여 검색이 빠릅니다.
- 삽입과 삭제 시, 정렬을 하기 때문에 저장시간이 다소 오래 걸립니다.
- 정렬된 순서(기본 오름차순)대로 보관하며 Comparable나 Comparator를 이용해 정렬방법을 지정할 수 있습니다.
TreeMap<K, V> treeMap = new TreeMap<K, V>();
성능 비교
Access | Search | Insertion | Deletion | |
---|---|---|---|---|
HashMap | N/A | O(1) | O(1) | O(1) |
Hashtable | N/A | O(1) | O(1) | O(1) |
LinkedHashMap | N/A | O(1) | O(1) | O(1) |
TreeMap | N/A | O(log(n)) | O(log(n)) | O(log(n)) |
HashMap과 LinkedHashMap, Hashtable은 Hash값으로 호출/삭제/삽입을 하므로 모든 연산에 있어 O(1)의 시간 효율성을 가집니다.
TreeMap은 이진 탐색 트리를 사용하므로, 검색/삽입/삭제의 시간 효율성은 log(n)을 가지게 됩니다.
HashTable | HashMap | LinkedHashMap | TreeMap | |
---|---|---|---|---|
내부로직 | Hashing | Hashing | Hashing | 이진 탐색 트리(BST : Binary Search Tree) |
동기화 | Thread safe | Not Thread safe | Not Thread safe | Not Thread safe |
정렬 순서 | 유지되지 않음 | 유지되지 않음 | 삽입순서 유지 | Comporator 가 정의되지 않을 경우 오름차순에 의해 자동 정렬 |
성능 | 동기화되므로 HashMap보다 약간 느림 | 가장 좋음 | 삽입순서를 유지하기 위하여 포인터값을 저장하므로 HashMap 보다 약간 느림 | 삽입과 삭제 후 재정렬해야하므로 가장 느림 |
Null Value | 허용하지 않음 | Key값으로 최대 한 개의 Null 허용, V값으로 복수의 Null 허용 | Key값으로 최대 한 개의 Null 허용, V값으로 복수의 Null 허용 | 허용하지 않음 |
사용 용도 | 쓰레드 세이프티가 요구될 때 사용 | 가장 좋은 퍼포먼스를 보이므로, 일반적으로 권장 | 삽입순서를 유지하고 싶다면 선택 | Comparator 에 의해 원소들을 정렬하고 싶다면 선택 |
Properties
- Hashtable의 하위 클래스이기 때문에 Hashtable의 모든 특징을 그대로 가지고 있습니다.
- Hashtable은 키와 값을 다양한 타입으로 지정이 가능하지만 Properties는 키와 값을 String 타입으로 제한한 컬렉션입니다.
.properties
라는 확장자를 가진 파일을 만들어 DB의 연결정보 등을 저장해두는 용도로 많이 쓰입니다.
Properties properties = new Properties();
간단한 사용법
- 파일을 직접 여는 클래스가 아니므로 FileReader 또는 FileInputStream 객체를 매개변수로 받습니다.
- 외부 리소스와 직접 연결되지 않으므로 확인된 예외가 throw되어 있지 않습니다. (예외 처리 필요)
load()
메소드를 통해 파일 정보를 넣어 줍니다.
db.properties
자바 프로젝트의 config
라는 패키지에 db.properties
라는 파일이 있다고 가정하겠습니다.
driver=org.postgresql.Driver
url=jdbc:postgresql://localhost:5432/postgres
username=postgres
password=#goodday#
properties파일 가져오기
import java.io.IOException;
import java.io.Reader;
import java.util.Properties;
public class EntryMain {
public static void main(String[] args) {
String resource = "config/db.properties";
Properties properties = new Properties();
try {
Reader reader = Resources.getResourceAsReader(resource);
properties.load(reader);
System.out.println(properties.getProperty("driver"));
System.out.println(properties.getProperty("username"));
System.out.println(properties.getProperty("password"));
System.out.println(properties.getProperty("url"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
코드를 실행해 보면 db.properties 파일을 담겨져 있는 4개의 정보가 콘솔에 표시되는 것을 볼 수 있습니다.
참고 : https://gangnam-americano.tistory.com/41
https://hackersstudy.tistory.com/26
https://minwan1.github.io/2018/07/03/2018-07-03-collection/
https://freestrokes.tistory.com/84
https://codevang.tistory.com/163
http://www.gisdeveloper.co.kr/?p=5160
https://st-lab.tistory.com/142
https://sup2is.github.io/2019/09/23/array-deque.html
댓글남기기