Map은 Collection 인터페이스를 상속하진 않았지만 Collection 자료구조에 포함시켜 이야기한다..
[ Collection 구조 정리글 : https://bangu4.tistory.com/194 ]
MAP 인터페이스
Map은 중복을 허용하지 않는 Key와 중복이 가능한 Value가 각각 쌍을 이루어 저장되는 자료구조이다.
1. Map 자료구조의 특징
- 중복 : 중복 불가 , index가 순차적 Key로 유일성을 가짐
- 순서 : 보장 불가
- 정렬 : 정렬 불가
- 동기화 (Thread-Safe) : 동기화 불가능, 불안전함
삽입 / 삭제 / 조회 연산이 광장히 빠르지만,
순서를 보장하지 않고, 정렬이 불가하다는 단점을 가지고 있다.
이러한 단점을 보완하기 위해서 자바에서는 HashMap , LinkedHashMap, TreeMap 세 가지의 클래스를 지원한다.
- HashMap
- 해시함수를 이용한 Map임
- 삽입 / 삭제 / 조회 연산의 O(1)을 보장하는 아주 빠른 자료구조
- 삽입 데이터의 순서를 보장하지 않음
- 정렬이 불가함
- LinkedHashMap
- 삽입 / 삭제가 맵보다 느림
- 삽입 순서를 보장함
- 정렬은 불가함
- TreeMap
- 삽입 / 삭제가 굉장히 느림,
- 삽입순서를 보장함
- Map이지만 유일하게 정렬이 가능함.
각각의 특징을 보면서 상황별로 어떠한 자료의 클래스를 사용할지 판단하면 된다.
Map을 써야하는데 정렬이 불가피하다면, TreeMap을 사용하면되고,
Map을 써야하는데 정렬은 필요없지만, 삽입순서를 기억해야한다면, LinkedHashMap을 쓰면된다.
그 외에는 당연이 가장 효율적이고 빠른 HashMap을 기본적으로 사용하자.
참고로 HashTable은 과거에 사용하던 클래스로 현재는 더 이상 지원하지 않는 클래스이니, 사용을 지양하는것이 좋습니다.
2. 주요 메소드
HashMap 메소드
void clear() | 해당 맵(map)의 모든 매핑(mapping)을 제거함. |
boolean containsKey(Object key) | 해당 맵이 전달된 키를 포함하고 있는지를 확인함. |
boolean containsValue(Object value) | 해당 맵이 전달된 값에 해당하는 하나 이상의 키를 포함하고 있는지를 확인함. |
V get(Object key) | 해당 맵에서 전달된 키에 대응하는 값을 반환함. 만약 해당 맵이 전달된 키를 포함한 매핑을 포함하고 있지 않으면 null을 반환함. |
boolean isEmpty() | 해당 맵이 비어있는지를 확인함. |
Set<K> keySet() | 해당 맵에 포함되어 있는 모든 키로 만들어진 Set 객체를 반환함. |
V put(K key, V value) | 해당 맵에 전달된 키에 대응하는 값으로 특정 값을 매핑함. |
V remove(Object key) | 해당 맵에서 전달된 키에 대응하는 매핑을 제거함. |
V replace(K key, V value) | 해당 맵에서 전달된 키에 대응하는 값을 특정 값으로 대체함. |
boolean replace(K key, V oldValue, V newValue) | 해당 맵에서 특정 값에 대응하는 전달된 키의 값을 새로운 값으로 대체함. |
int size() | 해당 맵의 매핑의 총 개수를 반환함. |
boolean remove(Object key, Object value) | 해당 맵에서 특정 값에 대응하는 특정 키의 매핑을 제거함. |
http://tcpschool.com/java/java_collectionFramework_concept : 주요메소드 참조
HashMap 예문 Code
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
public class HashMapExam {
public static void main(String[] args) {
// 객체생성
HashMap<Integer,Integer> map = new HashMap<>();
// put() 삽입연산으로 초기화
for (int i = 0; i < 10; i++)
map.put(i, i*i);
// KeySet()
HashSet<Integer> set = new HashSet<Integer>(map.keySet());
System.out.print("keySet() : ");
for(int i : set)
System.out.print(i+" ");
// get() 조회
System.out.println("\n\n4의 value : " + map.get(4)+"\n");
// remove() 삭제
System.out.println("remove(4) : " + map.remove(4)+"\n");
// getOrDefault - 가져올때 값이 없으면 Default값을 가져옴
System.out.println("map.getOrDefault(4, 16) : " + map.getOrDefault(4, 16)+"\n");
// containsKey
System.out.println("containsKey(4) : " + map.containsKey(4)+"\n");
// containsValue
System.out.println("containsValue(16) : "+ map.containsValue(16)+"\n");
// size() 크기
System.out.println("size : " + map.size()+"\n");
//replace() 변경 , put도 가능
map.replace(5, 5);
System.out.println("map.replace 수행후 get(5) : " + map.get(5)+"\n");
// 응용 put은 변경에도 쓰임, getOrDefault는 초기화에 많이쓰임
map.put(4, map.getOrDefault(4, 16)); // key 5에 4가 가지고 있는값을 얻어와 넣어주려하는데 4가 없으면 16이란 값을 넣어주는경우
System.out.println("getOrDefault로 4 다시 생성 : " + map.get(4) +"\n");
// Map의 단일객체 Entry
System.out.println("Map.Entry<>로 받는 entrySet() 메소드");
for(Map.Entry<Integer,Integer> m : map.entrySet()) {
map.put(m.getKey(), m.getKey()*m.getValue()); // 세제곱값으로 초기화
System.out.print(map.get(m.getKey())+" ");
}
System.out.println("\n");
// clear 모두제거
map.clear();
System.out.println("clear() 수행\n");
// isEmpty() 비었는지 확인
System.out.println("isEmpty? : " + map.isEmpty()+"\n");
}
}
TreeMap 메소드
[ Map.Entry 인터페이스는 Map 인터페이스의 내부 인터페이스로 맵에 저장되는 엔트리의 조작을 위한 메소드가 정의되어 있습니다. ]
NavigableMap<K, V> descendingMap() | 모든 맵을 역순으로 반환함. |
NavigableSet<k, > </k,>descendingKeySet() | 모든 키을 역순으로 반환함. |
K firstKey() | 해당 맵에서 현재 가장 작은(첫 번째) 키를 반환함. |
K lastKey() | 해당 맵에서 현재 가장 큰(마지막) 키를 반환함. |
K higherKey(K key) | 해당 맵에서 전달된 키보다 작은 키 중에서 가장 큰 키를 반환함. 만약 해당하는 키가 없으면 null을 반환함. |
K lowerKey(K key) | 해당 맵에서 전달된 키보다 큰 키 중에서 가장 작은 키를 반환함. 만약 해당하는 키가 없으면 null을 반환함. |
K ceilingKey(K key) | 해당 맵에서 전달된 키와 같거나, 전달된 키보다 큰 키를 반환함. 없으면 null을 반환함. |
K floorKey(K key) | 해당 맵에서 전달된 키와 같거나, 전달된 키보다 작은 키를 반환함. 없으면 null을 반환함. |
SortedMap<K, V> headMap(K toKey) | 해당 맵에서 전달된 키보다 작은 키로 구성된 부분만을 반환함. |
SortedMap<K, V> subMap(K fromKey, K toKey) | 해당 맵에서 fromKey(포함)부터 toKey(미포함)까지로 구성된 부분만을 반환함. |
SortedMap<K, V> tailMap(K fromKey) | 해당 맵에서 fromKey와 같거나, fromKey보다 큰 키로 구성된 부분만을 반환함. |
HashMap의 모든 메소드를 사용가능하므로 생략하고,
TreeMap에서만 사용가능한 메소드를 정리해보겠습니다.
TreeMap 예문 Code
import java.util.HashSet;
import java.util.Map;
import java.util.TreeMap;
public class TreeMapExam {
public static void main(String[] args) {
// TreeMap 객체생성
TreeMap<Integer,Integer> map = new TreeMap<>();
// 삽입과 동시에 정렬되는 자료구조
for (int i = 10; i > 0; i--)
map.put(i, i*i); //100,91,64,...9,4,1
// 출력
System.out.println("삽입과 동시에 정렬됨 : ");
for(int i : map.keySet())
System.out.print(map.get(i)+" "); //1,4,9,...64,91,100
// 역순 출력
System.out.println("\n\n역순 출력 : ");
for(int i : map.descendingKeySet())
System.out.print(map.get(i)+" "); //100,91,64,...9,4,1
System.out.println("\n\n최소값을 받아오는 다양한 메소드의 사용 : ");
System.out.print(map.pollFirstEntry().getKey()+" ");
System.out.print(map.firstEntry().getKey()+" ");
Map.Entry<Integer,Integer> m = map.firstEntry();
System.out.print(m.getValue()+" ");
System.out.print(map.firstKey()+" ");
}
}
최소값을 받아오는 메소드들에 대해서만 정리하였는데,
나머지도 사용은 똑같습니다.
보시면서 한번씩 사용을 해보시길 바랍니다.
3. 시간복잡도
HashMap 시간복잡도
get : O(1)
containsKey : O(1)
next : O(h/n) h는 테이블 용량
java 1.2 에서 나옴
특징 : 순서에 상관없이 저장됨, Null을 허용한다. thread-safe 보장하지 않는다.
LinkedHashMap 시간복잡도
get : O(1)
containsKey : O(1)
next : O(1)
java 1.4 에서 나옴
특징 : 순서대로 등록한다. Null을 허용한다. thread-safe 보장하지 않는다.
TreeMap 시간복잡도
get : O(log n)
containsKey : O(log n)
next : O(log n)
java 1.2 에서 나옴
특징 : 정렬이 되면서 추가가 됨
- null은 허용하지 않음
- thread-safe 보장하지 않는다.
'Work > Java' 카테고리의 다른 글
[Java] Lambda 람다식 (함수형 인터페이스와 메소드참조) - 총정리 (0) | 2021.07.26 |
---|---|
[Java] Comparable, Comparator 인터페이스 (0) | 2021.07.18 |
[Java] List 인터페이스와 클래스 - 총정리 (0) | 2021.07.06 |
[Java] Set 인터페이스와 클래스 - 총정리 (0) | 2021.07.02 |
[Java] 시간과 날짜 Class - 정리 (0) | 2021.06.30 |