[작성일: 2023. 02. 07]
컬렉션 프레임워크(Collection Framework)
컬렉션(collection)
- 여러 객체(데이터)를 모아놓은 것
프레임워크(framework)
- 표준화, 정형화된 체계적인 프로그래밍 방식
- 프로그래밍의 생산성이 올라가고 유지보수가 쉬워짐
컬렉션 프레임워크(collection framework)
- 컬렉션(다수의 객체)을 다루기 위한 표준화된 프로그래밍 방식
- 컬렉션을 쉽고 편리하게 다룰 수 있는 다양한 클래스 제공
- java.util 패키지에 포함
- 객체(데이터) 저장, 삭제, 검색, 정렬 등이 편리함.
컬렉션 클래스(collection class)
- 다수의 데이터를 저장할 수 있는 클래스
(Vector, ArrayList, HashSet)
컬렉션 프레임워크의 핵심 인터페이스
- List와 Set의 공통부분을 뽑아 Collection인터페이스에 정의함.
인터페이스 | 특징 |
List | - 순서가 있는 데이터의 집합 - 데이터의 중복을 허용함. ex) 대기자 명단 |
* 구현 클래스: ArrayList, LinkedList, Stack, Vector 등 | |
Set | - 순서를 유지하지 않는 데이터의 집합 - 데이터의 중복을 허용하지 않음. ex) 양의 정수 집합, 소수의 집합, 네 발 동물의 집합 |
* 구현 클래스: HashSet, TreeSet | |
Map | - 키(Key)와 값(Value)의 쌍으로 이루어진 데이터의 집합 - 순서는 유지되지 않음. - 키는 중복을 허용하지 않고, 값은 중복을 허용함. ex) 우편번호, 지역번호(전화번호), ID/PW |
* 구현 클래스: HashMap, TreeMap, Hashtable, Properties 등 |
Collection 인터페이스의 메서드
메서드 | 설명 |
boolean add(Object o) boolean addAll(Collection c) |
지정된 객체(o) 또는 Collection(c)의 객체들을 Collecion에 추가함. |
void clear() | Collection의 모든 객체를 삭제함. |
boolean contains(Object o) boolean containsAll(Collection c) |
지정된 객체(o) 또는 Collection의 객체들이 Collection에 포함되어 있는지 확인함. |
boolean equals(Object o) | 동일한 Collection인지 비교함. |
int hashCode() | Collection의 hash code를 반환함. |
boolean isEmpty() | Collection이 비어있는지를 확인함. |
Iterator iterator() | Collection의 Iterator를 얻어서 반환함. |
boolean remobe(Object o) | 지정된 객체를 삭제함. |
boolean removeAll(Collection c) | 지정된 Collection에 포함된 객체들을 삭제함. |
boolean retainAll(Collection c) | 지정된 Collection에 포함된 객체만을 남기고 다른 객체들은 Collection에서 삭제함. 이 작업으로 인해 Collection에 변화가 있으면 true, 아니면 false를 반환함. |
int size() | Collection에 저장된 객체의 개수를 반환함. |
Object[] toArray() | Collection에 저장된 객체의 객체배열(Object[])로 반환함. |
Object[] toArray(Object[] a) | 지정된 배열에 Collection의 객체를 저장해서 반환함. |
List 인터페이스
- 저장된 순서가 유지되고 중복을 허용함.
- List는 Collection 인터페이스의 자손이기 때문에 Collection의 메서드들도 사용할 수 있음.
메서드 | 설명 |
void add(int index, Object element) boolean addAll(int index, Collection c) |
지정된 위치(index)에 객체(element) 또는 컬렉션에 포함된 객체들을 추가함. 추가되면 그 자리에 있던 것이 사라지는 것이 아니라 뒤로 밀리게 됨. |
Object get(int index) | 지정된 위치에 있는 객체를 반환함. 읽기 |
int indexOf(Object o) | 지정된 객체의 위치를 반환함. (List의 첫 번째 요소로부터 순방향으로 찾음.) |
int lastIndexOf(Object o) | 지정된 객체의 위치를 반환함. (List의 마지막 요소로부터 역방향으로 찾음.) |
ListIrerator lisIterator() ListIrerator lisIterator(int index) |
List의 객체에 접근할 수 있는 ListIterator를 반환함. |
Object remove(int index) | 지정된 위치에 있는 객체를 삭제하고 삭제된 객체를 반환함. |
Object set(int index, Object element) | 지정된 위치(index)에 객체(element)를 저장함. 변경. |
void sort(Comparator c) | 지정된 비교자로 List를 정렬함. |
List subList(int fromindex, int toIndex) | 지정된 범위(from 부터 to)에 있는 객체를 반환함. |
Set 인터페이스
- 저장된 순서를 유지하지 않고 중복을 허용하지 않음.
- HashSet, TreeSet이 핵심
- Coolection 인터페이스와 동일하므로 참고할 것!
- 집합과 관련된 메서드(Collection에 변화가 있으면 true, 아니면 false를 반환함.)
메서드 | 설명 |
boolean addAll(Collection c) | 지정된 Coollection(c)의 객체들을 Collection에 추가함. (합집합) |
boolean containsAll(Collection c) | 지정된 Collection의 객체들이 Collection에 포함되어 있는지 확인함.(부분집합) |
boolean removeAll(Collection c) | 지정된 Collection에 포함된 객체들을 삭제함.(차집합) |
boolean retainAll(Collection c) | 지정된 Collection에 포함된 객체만 남기고 나머지는 삭제함.(교집합) 겹치는 것만 빼고 다 삭제함. |
Map 인터페이스
- 저장된 순서를 유지하지 않고 키는 중복을 허용하지 않고 값은 중복을 허용함.
- HashMap, TreeMap이 핵심
- LinkedHashMap은 Map이지만 순서를 유지함.
메서드 | 설명 |
void clear() | Map의 모든 객체를 삭제함. |
boolean containKey(Object key) boolean containsValue(Object value) |
지정된 key 객체와 일치하는 Map의 key 객체가 있는지 확인함. 지정된 value 객체와 일치하는 Map의 value 객체가 있는지 확인함. |
boolean equals(Object o) | 동일한 Map인지 비교함. |
Object get(Object key) | 지정한 key 객체에 대응하는 value 객체를 찾아서 반환함. |
int hashCode() | 해시코드를 반환함. |
boolean isEmpty() | Map이 비어있는지 확인함. |
Set keySet() | Map에 저장된 모든 key 객체를 반환함. |
Collection values() | Map에 저장된 모든 value 객체를 반환함. 반환타입이 Collection이기 때문에 순서나 중복이 있어도 되고 없어도 됨. |
Set entrySet() | Map에 저장되어 있는 key-value 쌍을 Map.Entry 타입의 객체로 저장한 Set으로 반환함. |
Object put(Object key, Object value) | Map에 value 객체를 key 객체에 연결하여 저장함. |
void putAll(Map t) | 지정된 Map의 모든 key-value를 추가함. |
Object remove(Object ley) | 지정된 key 객체와 일치하는 key-value 객체를 삭제함. |
int size() | Map에 저장된 key-value 쌍의 개수를 반환함. |
ArrayList
- ArrayList는 기존의 Vector를 개선한 것으로 구현원리와 기능적으로 동일
- ArrayList와 달리 Vector는 자체적으로 동기화 처리가 되어 있음.
- List인터페이스를 구현하므로 저장 순서가 유지되고 중복을 허용함.
- 데이터의 저장공간으로 배열을 사용함.(배열 기반)
생성자 | 추가 메서드 | 삭제 메서드 |
ArrayList() 기본 생성자 |
boolean add(객체) 객체 추가-> 성공하면 true 반환 |
bollean remove(Object o) 저장한 것 삭제 |
ArrayList(Collection c) 매개변수로 컬렉션을 줌. |
void add(int index Object element) 저장위치 지정 |
Object remove(int index) 특정 위치 삭제 |
ArrayList(int initialCapacity) 매개변수에 배열의 길이를 넣음. |
boolean addAll(Collection c) 컬렉션을 주면 요소를 그대로 저장 |
boolean removeAll(Collection c) 컬렉션을 지정해주면 컬렉션의 객체를 삭제하는 것 |
boolean addAll(int index, Collection c) | void clear() 모든 객체 삭제 |
검색 메서드 | 메서드 |
int indexOf(Object o) 객체가 몇 번째 저장되어있는지 찾기 못 찾으면 -1 반환 |
List subList(int fromIndex, int toIndex) from~to를 뽑아서 새로운 리스트를 만드는 것 to는 포함되지 않음. |
int lastIndexOf(Object o) 역방향으로 객체를 찾음 |
Object[] toArray() ArrayList의 객체 배열 반환 |
boolean contains(객체) 지정된 객체가 포함되어 있는지 |
boolean isEmpty() 비어있는지 확인 |
Object get(int index) 특정위치의 객체 반환, 객체 읽기 |
void trim ToSize() 빈 공간 제거 |
Object set(int index, Object element) 특정 위치의 객체를 변경 |
int size() 저장된 객체의 갯수 반환함. |
ArrayList에 저장된 객체의 삭제과정
- ArrayList에 저장된 세 번째 데이터(data [2])를 삭제하는 과정
* list.remove(2); 호출
1. 삭제할 데이터 아래의 데이터를 한 칸씩 위로 복사해서 삭제할 데이터를 덮어씀.
2. 데이터가 모두 한 칸씩 이동했으므로 마지막 데이터는 null로 변경함.
3. 데이터가 삭제되어 데이터의 개수가 줄었으므로 size의 값을 감소시킴.
* 마지막 데이터를 삭제하는 경우 1의 과정(배열 복사)는 필요 없음.
* 첫 번째 객체부터 삭제하는 경우 성능도 안 좋아지고 좋은 방법이 아님.
System.arraycopy(data, 3, data, 2, 2)
// data[3]에서 data[2]로 2개의 데이터를 복사
data[size-1] = null;
size--;
LinkedList
💡 배열의 장점
- 배열은 구조가 간단하고 데이터를 읽는 데 걸리는 시간(접근시간, access time)이 짧음.
- n번째 요소의 주소를 쉽게 계산할 수 있음.
- 인덱스가 n인 데이터의 주소 = 배열의 주소 + n * 데이터 타입의 크기
- 순차적인 데이터 추가(끝에 추가)와 삭제(끝부터 삭제)는 빠름.
💡 배열의 단점
- (실행 중) 크기를 변경할 수 없음.
- 크기를 변경해야 하는 경우 새로운 배열 생성 후 데이터를 복사해야 함.
➡️ 크기 변경을 피하기 위해 미리 큰 배열을 생성해 두면 메모리가 낭비됨.
- 비순차적인 데이터의 추가, 삭제에 시간이 많이 걸림.
➡️ 데이터를 추가하거나 삭제하기 위해 다른 데이터를 옮겨야 함.
- LinkedList는 위 배열의 단점을 보완
- 배열과 달리 링크드 리스트는 불연속적으로 존재하는 데이터를 연결(link)
- 데이터의 삭제: 단 한 번의 참조변경만으로 가능함.(다음 Node를 찾아감.)
- 데이터의 추가: 한 번의 Node 객체 생성과 두 번의 참조변경만으로 가능함.
- 불연속적인 리스트이기 때문에 데이터 접근성이 나쁨. (첫 요소는 다음 요소만 알지 그 다다음 요소는 잘 모름.)
더블리 링크드 리스트(doubly linked list)
- 이중 연결 리스트, 접근성 향상!
- 참조를 두 개 가지고 있어서 앞, 뒤로 이동하는 것이 다 가능함.
- 여전히 한 번에 2, 3개 이동하는 것은 불가능함
- 실제로 Java에서는 이중 연결 리스트로 구현되어 있음.
더블리 써큘러 링크드 리스트(doubly circular linked list)
- 이중 원형 연결리스트
- 마지막 요소의 다음을 맨 앞에 연결해 놓고 맨 첫 요소를 맨 끝 요소와 연결함. (이전 요소로 가면 맨 뒤로 갈 수 있음.)
ArrayList vs LinkedList 성능 비교
- 순차적으로 추가/삭제하는 것은 ArrayList가 빠름.
- 비순차적으로 데이터를 추가/삭제 하는 것은 LinkedList가 빠름.
- 접근시간(access time)은 ArrayList가 빠름
컬렉션 | 읽기(접근 시간) | 추가/삭제 | 비고 |
ArrayList | 빠름 | 느림 | 순차적은 추가/삭제는 더 빠름 비효율적인 메모리 사용 배열기반의 자료 구조 연속적 |
LinkedList | 느림 | 빠름 | 데이터가 많을 수록 접근성이 떨어짐. 연결 기반의 자료 구조 불연속적 |
Stack & Queue
✏️ 스택(Stack)
- LIFO(Last In First Out) 구조
- 마지막에 저장된 것을 제일 먼저 꺼내게 됨.
- push(저장) - pop(추출)
- 순차적으로 추가/삭제하는 ArrayList가 적합, 배열이 유리
- 호출 스택은 이전 글 참조
Stack st = new Stack(); st.pop();
✏️ 큐(Queue)
- FIFO(First In First Out) 구조
- 제일 먼저 저장된 것을 제일 먼저 꺼내게 됨.
- offer(저장) - poll(추출)
- 비순차적으로 추가/삭제하는 LinkedList가 적합.(삭제 시 자리이동 없음)
- Java에서는 인터페이스로 정의됨.(객체생성 x)
- Queue를 구현한 클래스를 사용(Java API) , LinkedList
Queue q = new LinkedList(); q.offer("o");
Stack 메서드 | 설명 |
boolean empty() | Stack이 비어있는지 알려줌. |
Object peek() | Stack의 맨 위에 저장된 객체를 반환. pop()와 달리 Stack에서 객체를 꺼내지는 않음. 비었을 때는 EmptyStackException 발생 맨 위에 뭐가 있는지 (꺼내지 않고) 보는 것 |
Object pop() | Stack의 맨 위에 저장된 객체를 꺼냄. 비었을 때는 EmptyStakException 발생 |
Object push(Object item) | Stack에 객체를 저장함. |
int search(Object o) | Stack에서 주어진 객체를 찾아 그 위치를 반환함. 못 찾으면 -1 반환 배열과 달리 위치는 0이 아닌 1부터 시작함. indexOf()하고 비슷함. |
Queue 메서드 | 설명 |
boolean add(Object o) | 지정된 객체를 Queue에 추가함. 성공하면 true 반환 저장공간이 부족하면 lllegalStateException 발생(예외 발생) |
boolean offer(Object o) | Queue에 객체 저장함. 성공하면 true, 실패하면 false를 반환함. (예외발생X) |
Object remove() | Queue에서 객체를 꺼내 반환함. 비어있으면 NoSuchElementException 발생(예외 발생. try-catch 활용) |
Object poll() | Queue에서 객체를 꺼내서 반환함. 비어있으면 null을 반환함.(예외 발생X) |
Object element() | 삭제없이 요소를 읽어옴. peek과 달리 Queue가 비었을 때 NoSuchElementException 발생 |
Object peek() | 삭제없이 요소를 읽음. Queue가 비어있으면 null을 반환함. |
import java.util.*;
class ex {
public static void main(String[] args) {
Stack st = new Stack();
Queue q = new LinkedList();
//Queue인터페이스의 구현체인 LinkedList
st.push("0");
st.push("1");
st.push("2");
q.offer("0");
q.offer("1");
q.offer("2");
System.out.println("= Stack =");
while(!st.empty()) { // 스택이 비어있는지 확인
System.out.println(st.pop());
// 스택에서 마지막 요소부터 하나씩 꺼냄
}
System.out.println("= Queue =");
while(!q.empty()) { // 스택이 비었는지 확인
System.out.println(q.poll());
// 큐에서 맨 앞 요소부터 하나씩 꺼냄
}
//결과
= Stack =
2
1
0
= Queue =
0
1
2
Stack & Queue의 활용
✏️ 스택(Stack)
- 수식계산, 수식 괄호검사, 워드프로세서의 undo/redo(작업 되돌리기), 웹브라우저의 뒤로/앞으로 버튼
ex) 다음 방문(현재 페이지) → 네이버 방문 → 구글 방문→ 뒤로 가기 누르면 구글→ 네이버→ 다음 순
✏️ 큐(Queue)
- 최근 5~7개 사용문서 목록(이전 작업으로 돌아가기 쉬움, 새로운 문서를 열면 제일 오래된 작업이 목록에서 사라짐), 인쇄작업, 대기목록, 버퍼(buffer)
Iterator
- 컬렉션에 저장된 데이터를 접근하는데 사용되는 인터페이스(읽기 전용)
- 컬렉션에 저장된 요소들을 읽어오는 방법을 표준화한 것
- List에서 Set으로 바꿨을 때 저장된 읽는 요소를 Iterator를 사용하면 읽는 방법을 바꾸지 않아도 됨.
- 한 번 다 끝까지 읽고 나면 iterator를 다시 얻어와야 함.(일회용)
- 컬렉션에 iterator()를 호출에서 Iterator를 구현한 객체를 얻어서 사용함.
- Enumeration은 Iterator의 구버전
- ListIerator는 Iterator의 접근성을 향상시킨 것(단방향 ➡️ 양방향)
- Map에는 Iterator()가 없음. keySet(), entrySet(), values()를 호출해야 함.
메서드 | 설명 |
boolean hasNext() | 읽어 올 요소가 남아있는지 확인함. 있으면 true, 없으면 false를 반환함. |
Object next() | 다음 요소를 읽어옴. next()를 호출하기 전에 hasNext()를 호출해서 읽어올 요소가 있는지 확인하는 것이 안전함. |
import java.util.*;
class ex {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
Iterator it = list.iterator();
// iterator는 일회용이기 때문에 끝까지 다 읽고 나면 다시 얻어와야 함.
while(it.hasNext()) { // 읽어올 요소가 있는지 확인
Object obj = it.next();
System.out.println(obj); // 다음 요소를 읽어옴
}
}
}
//Map에는 Iterator가 없어서 entrySet() 호출
Map map = new HashMap();
...
Iterator it = map.entrySet().ierator();
Arrays
- 배열을 다루기 위한 편리한 static 메서드 제공
- 새로운 배열을 생성해서 반환함.
✏️ 배열의 출력 - toString()
static String toString(boolean[] a) static String toString(int[] a) static String toString(float[] a) static String toString(Object[] a) // 등등
✏️ 배열의 복사 - copyOf(), copyOfRange()int[] arr = {0, 1, 2, 3, 4}; int[] arr2 = Arrays.copyOf(arr, arr.length); // 0, 1, 2, 3, 4 int[] arr3 = Arrays.copyOf(arr, 3); // 0, 1, 2 int[] arr4 = Arrays.copyOf(arr, 7); // 0, 1, 2, 3, 4, 0, 0 int[] arr5 = Arrays.copyOfRange(arr, 2, 4); // 2, 3 int[] arr6 = Arrays.copyOfRange(arr, 0, 7); // 0, 1, 2, 3, 4, 0, 0
✏️ 배열 채우기 - fill(), setAll()int[] arr = new int[5]; Arrays.fill(arr, 9); // 9, 9, 9, 9, 9 Arrays.setAll(arr, (i) -> (int)(Math.random()*5) + 1); // 1, 5, 2, 1, 1
✏️ 배열의 정렬과 검색 - sort(), binarySearch()
* 순차 검색
* 이진 검색(binarySearch())은 정렬된 배열에만 사용 가능함.int[] arr = { 3, 2, 0, 1, 4); int idx = Arrays.binarySearch(arr, 2); // idx=-5 잘못된 결과 // 이진 탐색은 정렬된 배열에만 사용 가능 Arrays.sort(arr); // 배열 정렬 System.out.println(Arrays.toString(arr)); // 0, 1, 2, 3, 4 int idx = Arrays.binarySearch(arr, 2); // idx = 2 올바른 결과
✏️ 다차원 배열 - deepToString(), deepEquals()int[] arr2D = {{11, 12}, {21, 22}}; System.out.porintln(Arrays.deepToString(arr2D)); // [[11, 12], [21. 22]] String[][] str2D = new String[][] {{"aaa", "bbb"}, {"aaa", "BBB"}}; String[][] str2D2 = new String[][] {{"aaa", "bbb"}, {"aaa", "BBB"}}; System.out.println(Arrays.deepEquals(str2D, Str2D2)); // true
✏️ 배열을 List로 변환 - asList(Object... a)List list = Arrays.asList(new Integer[]{1, 2, 3, 4, 5}); // 1, 2, 3, 4, 5 List list = Arrays.asList(1, 2, 3, 4, 5); // 1, 2, 3, 4, 5 list.add(6); // 읽기 전용이기 때문에 예외 발생 List list = new ArrayList(Arrays.asList(1, 2, 3, 4, 5));
✏️ 람다와 스트림 관련 배열 - paralleXXX(), spliterator(), stream()
Comparator와 Comparable
- 객체 정렬에 필요한 메서드(정렬기준 제공)를 정의한 인터페이스
- 정렬: 두 대상 비교 후 자리바꿈을 반복함.
Comparable 기본 정렬기준(default)을 구현하는데 사용
Comparator 기본 정렬기준 외에 다른 기준으로 정렬하고자 할 때 사용
public interface Comparator { int compare(Object o1, Object o2); // 두 객체 비교 boolean equals(Object obj); // equals를 오버라이딩 } public interface Comparable { int compareTo(Object o); // 주어진 객체를 자신과 비교 }
HashSet
- Set 인터페이스를 구현한 대표적인 컬렉션 클래스이기 때문에 순서를 유지하지 않고 중복을 허용하지 않음.
- 순서를 유지하려면 LinkedHashSet 클래스를 사용하면 됨.
- HashSet은 객체를 저장하기 전에 기존에 같은 객체가 있는지 확인함.(중복여부 때문에)
- 같은 객체가 없으면 저장하고, 있으면 저장하지 않음.
- equals()와 hashCode()가 오버라이딩 되어 있어야 중복여부를 확인할 수 있음.
메서드 1 | 메서드 2 | 메서드 3 |
HashSet() | boolean add(Object o) 저장할 객체의 equals()와 hashCode()를 호출 |
void clear() 모두 삭제 |
HashSet(Collection c) 생성자 |
boolean addAll(Collection c) 합집합 |
boolean contains(Object o) |
HashSet(int initialCapacity) 초기용량(보통 2배) |
boolean remove(Object o) | boolean containsAll(Collection c) 여러 객체의 모든 포함여부 |
HashSet (int initialCapacity, float loadFactor) 언제 용량 늘릴 건지 |
boolean removeAll(Collection c) 교집합 |
Object[]to Array() |
int size() 저장된 객체의 수 |
boolean retainAll(Collection c) 조건부 삭제, 차집합 |
Object[]to Array(Object[] a) 객체배열로 반환 |
boolean isEmpty() | Iterator iterator() |
impor java.util.*;
class ex{
public static void main(String[] args) {
Object[] objArr = {"1", new Integer(1), "2", "3", "3", "4", "4"};
Set set = new HashSet();
for(int i=0; i < objArr.length; i++) {
System.out.println(set.add(objArr[i]));
}
System.out.println(set);
Iterator it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
class ex2 {
public static void main(String[] args) {
HashSet set = new HashSet();
set.add("abc");
set.add("abc"); // 중복이라 저장 안 됨
set.add(new Person("David", 10));
set.add(new Person("David", 10));
System.out.println(set);
}
}
// equals()와 hashCode()를 오버라이딩 해야 HashSet이 바르게 동작함.
class Person {
String name;
int age;
#Override
public int hashCode() {
return Objects.hash(name, age); // iv값
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Person)) return false;
Person p = (Person) obj;
// 나 자신(this)의 이름과 나이를 p와 비교
return this.name.equals(p.name) && this.age==p.age;
}
Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + ":" + age;
}
}
TreeSet
- 범위탐색, 정렬
- 이진 탐색 트리(binary search tree)로 구현
- 범위 탐색과 정렬에 유리함
- 이진 트리는 모든 노드가 최대 2개(0~2개)의 하위 노드(자식)를 가짐.
- 각 요소(node)가 나무(tree) 형태로 연결(LinkedList의 변형)
- 데이터 저장 과정 boolean add(Object o)
class TreeNode {
TreeNode left; // 왼쪽 자식노드
Object element; // 저장할 객체
TreeNode right; // 오른쪽 자식노드
}
생성자 또는 메서드 | 설명 |
TreeSet() | 기본 생성자 |
TreeSet(Collection c) | 주어진 컬렉션을 저장하는 TreesSet 생성 |
TreeSet(Comparator comp) | 주어진 정렬기준으로 정렬하는 TreeSet 생성 Comparator: 비교 기준 제공(없으면 기본 객체 기준인 Comparable 이용) |
Object first() | 정렬된 순서에서 첫 번째 객체를 반환함. |
Object last() | 정렬된 순서에서 마지막 객체를 반환함. |
Object ceiling(Object o) | 지정된 객체와 같은 객체를 반환함. 없으면 큰 값을 가진 객체 중 제일 가까운 값의 객체를 반환함. 그것도 없으면 null |
Object floor(Object o) | 지정된 객체와 같은 객체를 바노한함. 없으면 작은 값을 가진 객체 중 제일 가까운 값의 객체를 반환함. 그것도 없으면 null |
Object higher(Object o) | 지정된 객체보다 큰 값을 가진 객체 중 제일 가까운 객체를 반환함. 없으면 null |
Object lower(Object o) | 지정된 객체보다 작은 값을 가진 객체 중 제일 가까운 값의 객체를 반환함. 없으면 null |
SortedSet subSet(Object fromElement, Object toElement) | 범위 검색(formElement와 toElement 사이)의 결과를 반환함. 끝 범위인 toElement는 범위에 포함되지 않음. |
SortedSet headSet(Object to Element) | 지정된 객체보다 작은 값의 객체들을 반환함. |
SortedSet tailSet(Object fromElement) | 지정된 객체보다 큰 값의 객체들을 반환함. |
이진 탐색 트리(binary search tree)
- 부모보다 작은 값은 왼쪽, 큰 값은 오른쪽에 저장함.(이진 트리에는 이런 조약이 없음.)
- 이진 트리의 한 종류임.
- 데이터가 많아질 수록 추가/삭제에 시간이 더 걸림.(트리가 커질수록 부모와의 비교 횟수가 증가함.)
트리 순회(tree traversal)
- 이진 트리의 모든 노드를 한 번씩 읽는 것
- 부모를 먼저 읽는 것은 전위 순회, 부모를 나중에 읽는 것을 후위 순회라고 함.
- 레벨 순회: 한 층씩 순서대로 읽는 것
- 중위 순회: 오름차순으로 정렬 됨.
HashMap
- Map 인터페이스를 구현한 대표적인 컬렉션 클래스로 데이터를 키와 값의 쌍으로 저장함.
- HashMap은 신버전으로 동기화가 되어있지 않음.
- Hashtable은 구버전으로 동기화가 되어있음.
- 순서를 유지하려면 LinkedHashMap 클래스를 사용하면 됨.
- TreeMap은 범위 검색과 정렬에 유리한 컬렉션 클래스로 HashMap보다 데이터 추가/삭제에 시간이 더 걸림.
- 해싱기법으로 데이터를 저장하며 데이터가 많아도 검색이 빠름.
키(Key) 컬렉션 내의(key) 중에서 유일해야 함.
값(Value) 키(key)와 달리 데이터의 중복을 허용함.
HashMap map = new HashMap(); map.put("myId", "1234"); map.put("asdf", "1111"); map.put("asdf", "1234"); // myId, 1234와 asdf 1234만 저장 됨. // key가 중복인 것이 있어서 새 값으로 엎어서 저장됨.
메서드 1 | 메서드 2 | 메서드 3 |
HashMap() 기본 생성자 |
Object put(Object key, Object value) 데이터를 쌍으로 저장 |
int size() |
HashMap(int initialCapacity) 배열 초기용량 지정 |
void putAll(Map m) | booleanisEmpty() |
HashMap(int initialCapacity, float loadFactor) | Object remove(Object key) | void clear() |
HashMap(Map m) 다른 맵을 해시맵으로 변경 |
Object replace(Object key, Object value) 새로운 값으로 바꿔서 저장 |
Object clone() 복제하기 |
Set entrySet() 키-밸류를 얻을 수 있음. |
boolean replace(Object key, Object oldValue, Object newValue) | |
Set keySet() 키값만 얻음. |
Object get(Object key) 키값을 넣고 밸류값을 반환함. |
boolean containsKey(Object key) |
Collection values() 값만 얻음. |
Object getOrDefault(Object key, Object defaultValue) 없는 키값을 넣었을 때 지정된 값을 반환하게 하는 메서드 |
boolean containsValue(Object value) |
import java.util.*;
class ex {
public static void main(String[] args) {
HashMap map = new HashMap();
map.put("myId", "1234");
map.put("asdf", "1111");
map.put("asdf", "1234");
// 키 값이 같다고 에러가 나지 않고 값이 마지막 값으로 변경됨.
Scanner s = new Scanner(System.in);
while(true) {
System.out.println("id와 password를 입력하세요.");
System.out.print("id : ");
String id = s.nextLine().trim();
System.out.printl("password : ");
String password = s.nextLine().trim();
System.out.println();
if(!map.containsKey(id)) {
System.out.println("입력하신 id는 존재하지 않습니다. 다시 입력해주세요.");
continue;
}
if(!(map.get(id)).equals(password)) {
System.out.println("비밀번호가 일치하지 않습니다. 다시 입력해주세요.");
} else {
System.out.println("id와 비밀번호가 일치합니다.");
break;
}
}
}
}
해싱(Hashing)
- 해시함수(hash function)로 해시테이블(hash table)에 데이터를 저장하고 검색하는 것
- 해시테이블은 배열과 링크드 리스트가 조합된 형태(접근성이 좋고 변경에 유리함.)
✏️ 해시테이블에 저장된 데이터 가져오는 과정
1. 키로 해시함수를 호출해서 해시코드를 얻음.
2. 해시코드(해시함수의 반환값, 배열의 인덱스)에 대응하는 링크드리스트를 배열에서 찾음.
3. 링크드리스트에서 키와 일치하는 데이터를 찾음.
** 해시함수는 같은 키에 대해 항상 같은 해시코드를 반환해야 함. 서로 다른 키일지라도 같은 값의 해시코드를 반환할 수도 있음.
Collections 클래스
✏️ 컬렉션을 위한 메서드(static)
- 컬렉션 채우기, 복사, 정렬, 검색 - fill(), copy(), sort(), binarySearch() 등
- 컬렉션의 동기화 - synchronizedXXX()
static Collection 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(...));
- 변경불가(readOnly) 컬렉션 만들기 - unmodifiableXXX()
static Collection unmodifiableCollection(Collection c) static List unmodifiableList(List list) static Set unmodifiableSet(Set s) static Map unmodifiableMap(Map m) static NavigableSet unmodifiableNvigableSet(NvigablesSet s) static SortedSet unmodifiableSortedSet(SortedSet s) static NavigableMap unmodifiableNvigableMap(NvigablesMap s) static SortedMap unmodifiableSortedMap(SortedMap m)
- 싱클톤 컬렉션(객체 하나만 저장하는 메서드) 만들기 - singletonXXX()static List singletonList(Object o) static Set singleton(Object o) static Map singletonMap(Object key, Object value)
- 한 종류의 객체만 저장하는 컬렉션 만들기 - checkedXXX()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 type) static Queue checkedQueue(Queue queue, class type) static NavigableSet checkedNvigableSet(NvigablesSet s, class type) static SortedSet checkedSortedSet(SortedSet s, class type) static NavigableMap checkedNvigableMap(NvigablesMap s, class keyType, class valueType) static SortedMap checkedSortedMap(SortedMap m, class keyType, class valueType) List list = new ArrayList(); List chedckedList = checkedList(list, String.class); // String만 저장 가능 checkedList.add("abc"); // OK checkedList.add(new Integer(3)); // 에러
🐣 해당 게시글은 자바의 정석(남궁성 님) 영상으로 함께 공부하며 요약/정리한 글입니다.
🐣 입문 개발자가 작성한 글이므로 틀린 내용이나 오타가 있을 수 있습니다.