1. Map<K,V> 컬랙션의 특징
- Map<K,V>는 별도의 인터페이스로 존재
1)Key와 Value 한 쌍으로 데이터를 저장
-Key(키)와 Value(값)의 한쌍으로 데이터 저장
- 엔트리(entry) : 한쌍의 데이터
-Map.Entry 타입으로 정의
2)Key는 중복 저장 불가, Value 중복 가능
-데이터를 구분하는 기준이 Key 값이기 때문에 Key값은 중복될 수 없음
-Value값은 Key값으로 구분해 가져올 수 있으므로 중복 허용
(Key값이 다르면 Value값이 동일하다고 해도 구분 가능)
2. Map<K,V> 인터페이스의 주요 메서드
구분 | 메서드명 | 기능 |
데이터 추가 | put(K key, V value) | 입력매개변수의 (Key,Vlaue)를 Map 객체에 추가 |
putAll(Map<?extends K, ? extends V)m | 입력매개변수의 Map 객체를 통째로 추가 | |
데이터 변경 | replace(K key, V value) | Key에 해당하는 값을 Value값으로 변경(old값 리턴) (단, 해당 key가 없으면 null 리턴) |
replace(K key, V oldValue, V newValue_ | (key, oldValue)의 쌍을 갖는 엔트리에서 oldValue를 newValue로 변경 (단, 해당 엔트리가 없으면 false를 리턴) |
|
데이터 정보 추출 | get(Object key) | 매개변수의 Key 값에 해당하는 oldValue를 리턴 |
containsKey(Object key) | 매개변수의 Key값이 포함돼 있는지 여부 | |
containsValue(Object Value) | 매개변수의 Value값이 포함돼 있는지 여부 | |
KeySet() | Map 데이터들 중 Key들만 뽑아 Set 객체로 리턴 | |
entrySet() | Map의 각 엔트리들을 Set 객체로 담아 리턴 | |
size() | Map에 포함된 엔트리의 개수 | |
데이터 삭제 | remove(Object Key) | 입력매개변수의 Key를 갖는 엔트리 삭제 (단, 해당 Key가 없으면 아무런 동작을 하지 않음) |
remove(Object key, Object value) | 입력매개변수의 (key,value)를 갖는 엔트리 삭제 (단, 해당 엔트리가 없으면 아무런 동작하지 않음) |
|
clear() | Map 객체 내의 모든 데이터 삭제 |
3. HashMap<K,V>
-Key값의 중복을 허용하지 않음
-Key값의 중복 여부를 확인하는 메커니즘
->Key 객체의 hashCode() 값이 같고, equals() 메서드가 true를 리턴하면 같은 객체로 인식
-Key값을 HashSet<E>로 구현한 Map<K,V>객체
-입출력 순서는 동일하지 않을 수도 있음(HashSet<E>의 특성)
-초기 저장 용량의 기본값 16
- HashMap<K,V>의 주요 메서드
1) 데이터 추가
Map<Integer,String>hmap1 = new HashMap<Integer,String>();
//1.put(K key, V value)
hmap1.put(2,"나다라");
hmap1.put(1,"가나라");
hmap1.put(3,"다라마");
System.out.println(hMap1.toString()); //{1=가나다, 2=나다라, 3=다라마}
//2.putAll(<Map ? extends k,?extends V>m)
Map<Integer,String>hMap2 = new HashMap<Integer,String>();
hMap2.putAll(hMap1);
System.out.println(hMap2.toString()); //{1=가나다, 2=나다라, 3=다라마}
2) 데이터 변경
//3.replace(K key, V value)
hMap2.replace(1,"가가가");
hMap2.replace(4,"라라라"); //동작하지 않음
System.out.println(hMap2.toString()); //{1=가가가, 2=나나나, 3=다라마}
//4.replace(K key, V value,V oldValue, V newValue)
hMap2.replace(1,"가가가","나나나");
hMap2.replace(2,"다다다","라라라"); //동작하지 않음
System.out.println(hMap2.toString()); // {1=나나나, 2=나다라, 3=다라마}
3) 데이터 정보 추출
- keySet() 메서드는 현재 저장돼 있는 엔트리 중 Key 값만을 Set<E>로 가져옴
- entrySet() 메서드는 Map<K,V>에 포함된 모든 엔트리를 set<E>으로 가져올 수 있음
-> Set<E> 객체의 원소타입이 엔트리
//5.V get(Object key)
System.out.println(hMap2.get(1)); //나나나
System.out.println(hMap2.get(2)); //나다라
System.out.println(hMap2.get(3)); //다라마
//6.containsKey(Object key)
System.out.println(hMap2.containsKey(1)); //true
System.out.println(hMap2.containseKey(5)); //false
//7.containsValue(Object value)
System.out.println(hMap2.containsValue("나나나"); //true
System.out.println(hMap2.containsValue("다다다"); //false
//8.Set<K> KeySet()
System.out.println(keySet.toString()); //[1,2,3]
//9.Set<Map.Entry<K,V>>entrySet()
Set<Map.Entry<Integer,String>>entrySet = hMap2.entrySet();
System.out.println(entrySet);
//10.size()
System.out.println(hMap2.sizes()); //3
4) 데이터 삭제
//11.remove(Object key)
hMap2.remove(1);
hMap2.remove(4); //동작하지 않음
System.out.println(hMap2.toString()); //{2=나다라, 3=다라마}
//12.remove(Object key, Object value)
hMap2.remove(2,"나다라");
hmap2.remove(3,"다다다"); //동작하지 않음
System.out.println(hMap2.toString()); //{3=다라마}
//13.clear()
hMap2.clear();
Sysetm.out.println(hMap2.toString()); //{}
5) HashMap<K,V>에서 Key의 중복 확인 메커니즘
- equals() 메서드 오버라이딩
-> 두 객체의 필드 값이 같을 때 true 리턴
- hashCode() 메서드 오버라이딩
-> 필드값을 기준으로 해시코드 생성
class C {
int data;
public C(int data) {
this.data =data;
}
//Override
public boolean equals(Object obj) {
if(obj instanceof C) {
this.data = ((C)obj).data;
return true;
}
return false;
}
//override
public int hashCode() {
return Objects.hash(data);
}
}
public class HashMapMachnism {
public static void main(String[] args) {
Map<C,String>hashMap3 = new HashMap<>();
C c1 = new C(3);
C c2 = new C(3);
System.out.println(c1 == c2);
System.out.println(c1.equals(c2));
System.out.println(c1.hashCode() + "," +c2.hashCode());
hashMap3.put(c1, "첫 번째");
hashMap3.put(c2, "두 번째");
System.out.println(hashMap3.size()); //1
}
}
4. Hashtable<K,V>
- HashMap<K,V>구현 클래스가 단일 쓰레드에 적합한 반면, Hashtable은 멀티 쓰레드에 안정성을 가짐
- 하나의 Map<K,V> 객체를 2개의 쓰레드가 동시에 접근할 떄 HashTable<K,V> 내부의 주요 메서드가 동기화 메서드로 구현돼 있으므로 멀티 쓰레드에서 안전하게 동작
Map<Integer,String> hTable1 = new Hashtable<Integer,String>();
5. LinkedHashMap<K,V>
- HashMap<K,V> 기본 특징 + 입력 데이터의 순서정보를 추가로 갖고 있는 컬렉션
- 저장 데이터를 출력하면 항상 입력된 순서대로 출력
- Key를 LinkedHashSet<E>로 관리 (HashMap<K,V>에서는 Key를 HashSet<E>로 관리)
Map<Integer,String>lhMap1 = new LinkedHashMap<Integer,String>();
6. TreeMap<K,V>
- Map<K,V>의 기본 기능 + 정렬 및 검색 기능이 추가된 컬렉션
- 입력 순서와 관계없이 데이터를 Key값의 크기 순으로 저장
- Key 객체는 크기 비교의 기준을 갖고 있어야 함
- ShorteMap와 NavigableMap을 상속
- TreeMap<K,V>로 선언해야 SortedMap<K,V>와 NavigableMap<K,V>에서 추가된 정렬 및 추가 메서드 호출 가능
//Map<K,V>로 객체 타입을 선언할때
Map<Integer, String> treeMap = new TreeMap<Integer,String>();
treeMap. Map<K,V> 메서드만 사용 가능
//TreeMap<K,V>로 객체 타입을 선언할때
TreeMap<Integer,String> treeMap = new TreeMap<Integer,String>();
treeMap.Map<K,V> 메서드와 추가된 정렬/검색 메서드 사용 가능
- TreeMap<K,V>의 주요 메서드
->TreeSet<E>와 비슷
-> 데이터가 (Key,Value)쌍의 엔트리 형태로 저장되기 때문에 Key와 엔트리에 데잍를 검색하거나 추출하는 메서드가 포함
1) TreeMap<K,V>의 객체 생성 및 데이터 추가와 출력
TreeMap<Integer,String> treeMap = new TreeMap<Integer,String>();
for(int i=20; i>0; i-=2)
treeMap.put(i,i+"번째 데이터"):
System.out.println(treeMap.toString()); //{2=2번째 데이터, 4=4번째 데이터,...,20=20번째 데이터}
2) 데이터 검색
-firstKey(),firstEntry()는 각각 첫 번째 검색 데이터의 Key값과 엔트리를 가져옴
-lastKey(),lastEntry()는 각각 마지막 검색 데이터의 Key값과 엔트리를 가져옴
-lowerKey(),lowerEntry()는 각각 입력된 매개변수보다 가장 작은 인접한 값
-higherKey(),higherEntry()는 각각 입력된 매개변수보다 가장 큰 인접한 값
//1.firstKey()
System.out.println(treeMap.firstKey()); //2
//2.firstEntry()
System.out.println(treeMap.firstEntry()); //2=2번째 데이터
//3.lastKey()
System.out.println(treeMap.lastKey()); //20
//4.lastEntry()
System.out.println(treeMap.lastEntry()); //20=20번째 데이터
//5.lowerKey(K key)
System.out.println(treeMap.lowerKey(11)); //10
System.out.println(treeMap.lowerKey(10)); //8
//6.higherKey(K key)
System.out.println(treeMap.higherKey(11)); //12
System.out.println(treeMap.higherKey(10)); //12
3) 데이터 꺼내기
- pollFirstEntry(), pollLastEntry()는 각각 가장 작은 Key값의 엔트리와 가장 큰 Key값의 엔트리를 꺼내오는 메서드
-> 실제 TreeMap<K,V> 객체에서 데이터를 꺼내기 떄문에 데이터의 개수는 꺼낸만큼 줄어듬
//7.pollFirstEntry()
System.out.println(treeMap.pollFirstEntry()); //2=2번째 데이터
System.out.println(treeMap.toString()); //{4=4번째 데이터, 6=6번째 데이터, ..., 20=20번째 데이터}
//8.pollLastEntry()
System.out.println(treeMap.pollLastEntry()); //20=20번째 데이터
System.out.println(treeMap.toString()); //{4=4번째 데이터, 6=6번째 데이터, ..., 18=18번째 데이터}
4) 데이터 부분 집합(subMap)의 생성
//9.SortedMap<K,V> headMap(K toKey)
SortedMap<Integer,String> sortedMap = treeMap.headMap(8);
System.out.println(sortedMap); //{4=4번째 데이터, 6=6번째 데이터}
//10.NavigableMap<K,V> headMap(K toKey, boolean inclusive)
NavigableMap<Integer,Stirng>navigableMap = treeMap.headMap(8,true);
System.out.println(navigableMap); //{4=4번째 데이터, 6=6번째 데이터, 8=8번째 데이터}
//11.SortedMap<K,V> tailMap(K toKey)
sortedMap=treeMap.tailMap(14);
System.out.println(sortedMap); //{14=14번째 데이터, 16=16번째 데이터, 18=18번째 데이터}
//12.NavigableMap<K,V> tailMap(K toKey, booelean inclusvie)
navigableMap=treeMap.tailMap(14,false);
System.out.println(navigableMap); //{16=16번째 데이터, 18=18번째 데이터}
//13.SortedMap<K,V> subMap(K fromKey, K toKey)
sortedMap = treeMap.subMap(6,10);
System.out.println(sortedMap); //{6=6번째 데이터, 8=8번째 데이터}
//14.NavigableMap<K,V> subMap(K fromKey, booelan frominclusive, K toKey, boolean toinclusive)
navigableMap = treeMap.subMap(6,false,10,true);
System.out.println(navigableMap); //{8=8번째 데이터, 10=10번째 데이터}
5) 데이터 정렬
//15.NavigableSet<K> descendingKeySet()
NavigableSet<Integer> navigableSet = treeMap.descendingKeySet();
System.out.println(navigableSet); //[18,16,14,...,4]
System.out.println(navigableSet.descendingSet()); //[4,6,8,...,18]
//16.NavigableMap<K,V> descendingMap()
System.out.println(navigableMap); //{18=18번째 데이터, 16=16번째 데이터,..,4=4번째 데이터}
System.out.println(navigableMap.descendingMap()); //{4=4번째 데이터, 6=6번째 데이터,..,18=18번째 데이터}
6) 사용자 클래스의 크기 비교 기준 제공
-Key값의 크기를 비교해 정렬 수행
-1) Comparable<T> 제네릭 인터페이스 구현
class MyComparableClass implements Comparable<MyComparableClass> {
int data1;
int data2;
public MyComparableClass(int data1, int data2) {
this.data1 = data1;
this.data2 = data2;
}
//크기 비교의 기준 설정
//Override
public int compareTo(MyComparableClass o) {
if(this.data1 < o.data1) return -1;
else if(this.data1 == o.data1) retrun 0;
else return 1;
}
//Override
public String toString() {
return "data1="+data1+"을 갖고 있는 클래스";
}
}
- 2) TreeMap<K,V> 객체를 생성하면서 Compartor<T>객체 제공
TreeMap<MyClass,String> treeMap5 = new TreeMap<MyClass, String>(new Comparator<MyClass<() {
//override
public int compare(MyClass o1, MyClass o2) {
if(o1.data1 < o2.data1) return -1;
else if(o1.data1 == o2.data1) return 0;
else return 1;
}
});
'Java > 문법' 카테고리의 다른 글
17 - 6장 Queue<E> 컬렉션 인터페이스 (0) | 2023.06.19 |
---|---|
17 - 5장 Stack<E> 컬렉션 클래스 (0) | 2023.06.19 |
17 - 3장 Set<E> 컬렉션 인터페이스 (2) (2) | 2023.06.18 |
17 -3 장 Set<E> 컬렉션 인터페이스 (1) (0) | 2023.06.16 |
17 - 2장 List<E> 컬렉션 인터페이스 (0) | 2023.06.16 |