본문 바로가기
Work/Java

[Java] Map 인터페이스와 클래스 - 총정리

Map은 Collection 인터페이스를 상속하진 않았지만 Collection 자료구조에 포함시켜 이야기한다..

 [ Collection 구조 정리글 : https://bangu4.tistory.com/194 ]

 

[Java] Java Collection 구조 정리

자바의 Collection 자료구조 자바에서 사용하는 컬렉션 프레임워크의 주요 클래스표이다. 좀더 상세한 클래스와 구현 인터페이스는 아래와 같다 1. Collection Interface Iterator 인터페이스를 상속한 Col

bangu4.tistory.com

 

 

 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 보장하지 않는다.