HashMap
HashTable과 HashMap은 Vector와 ArrayList의 관계와 같아서 HashTable보다는 새로운 버전인 HashMap을 사용하는게 좋다.
HashMap은 Map을 구현했으므로 키(key)와 값(value)의 쌍의 특징에 해싱을 사용하기 때문에 많은 양의 데이터를 검색하는데 있어서 뛰어난 성능을 보인다.
//HashMap의 코드 일부
public class HashMap extends AbstractMap implement Map, Cloneable, Serializezble{
transient Entry[] table;
...
static class Entry implements Map.Entry {
final Object key; //키
Object value; //값
...
}
}
HashMap은 Entry라는 내부 클래스를 정의하고, 다시 Entry타입의 배열을 선언하고 있다. 키와 값은 별개의 값이 아니라 서로 관련된 값이기 때문에 각각보다는 하나의 클래스로 정의해서 하나의 배열로 다루는 것이 데이터의 무결성적인 측면에서 바람직하다.
비객체지향적인 코드 | 객체지향적인 코드 |
Object[] Key Object[] Value |
Entry[] table; class Entry{ Object Key; Object Value; } |
HashMap은 (Object, Object)의 형태로 저장하기 때문에 어떠한 객체도 저장할 수 있지만 키는 주로 String을 대문자 또는 소문자로 통일해서 사용한다.
메서드 | 설명 |
HashMap() | HashMap 객체를 생성 |
HashMap(int initialCapacity) | 지정된 값을 초기용량으로하는 HashMap 생성 |
HashMap(int initalCapacity, float loadFactor) |
지정된 초기 용량과 load factor의 HashMap 생성 |
HashMap(Map m) | 지정된 Map의 모든 요소를 저장하는 HashMap생성 |
void clear() | HashMap에 저장된 모든 객체를 제거 |
Object clone() | 현재 HashMap을 복제해서 반환 |
boolean containsKey(Object key) | HashMap에 지정된 키가 포함돼있는지 알려준다.(포함 true) |
boolean containsValue(Object value) | HashMap에 지정된 값이 포함돼있는데 알려준다.(포함 true) |
set entrySet() | 저장된 키와 값을 엔트리(키와 값의 결합)의 형태로 Set에 저장해서 반환 |
Object get(Object key) | 지정된 키의 값을 반환, 키를 못찾으면, 기본값으로 지정된 객체를 반환 |
Object getOrDefault(Object key, Object defaultValue) |
지정된 키의 값을 반환한다. 키를 못찾으면 defaultValue로 지정된 객체 반환 |
boolean isEmpty() | HashMap이 비었는지 알려준다. |
Set keySet() | HashMap에 저장된 모든 키를 Set으로 반환 |
Object put(Object key, Object value) | 지정된 키와 값을 HashMap에 저장 |
void putAll(Map m) | Map에 저장된 모든 요소를 HashMap에 저장 |
Object remove(Object key) | HashMap에서 지정된 키로 저장된 값을 제거 |
Object replace(Object key, Object value) | 지정된 키의 값을 지정된 객체로 대체 |
boolean replace(Object key, Object value, Object newValue) |
지정된 키와 객체가 모두 일치하는 경우에만 새로운 객체로 대체 |
int size() | HashMap에 저장된 요소의 개수를 반환 |
Collection values() | HashMap에 저장된 모든 값을 컬렉션의 형태로 반환 |
HashMap 예제
import java.util.*;
class HashMapEx1 {
public static void main(String[] args) {
HashMap map = new HashMap();
map.put("myId", "1234");
map.put("asdf", "1111");
map.put("asdf", "1234"); // !키의 중복으로 저장되지 않음
Scanner sc = new Scanner(System.in);
while(true){
System.out.print("id :");
String id = sc.nextLine().trim(); //trim() 좌우 공백제거
System.out.print("password :");
String passwd= sc.nextLine().trim();
if(!map.containsKey(id)) {
System.out.println("입력하신 id는 존재하지 않습니다.");
continue;
}
if(!(map.get(id)).equals(password)){
System.out.println("비밀번호가 일치하지 않습니다.");
} else {
System.out.println("로그인 성공");
break;
}
}
}
}
import java.util.*;
class HashMapEx2 {
public static void main(String[] args) {
HashMap map = new HashMap();
map.put("김자바", new Integer(100));
map.put("이자바", new Integer(100));
map.put("박자바", new Integer(80));
map.put("최자바", new Integer(90));
Set set = map.entrySet();
Iterator it = set.iterator();
while(it.hasNext()) {
Map.Entry e = (Map.Entry)it.next();
System.out.println("이름 : "+e.getKey() + ", 점수 : "+ e.getValue());
}
set = map.keySet();
System.out.println("참가자 명단 : " + set);
Collection values = map.values();
it = values.iterator();
int total = 0;
while(it.hasNext()){
Integer i = (Integer)it.next();
total += i.intValue();
}
System.out.println("총점 : " + total);
System.out.println("평균 : " + (float)total/set.size());
System.out.println("최고점수 : " + Collections.max(values));
System.out.println("최저점수 : " + Collections.min(values));
}
}
============
실 행 결 과
============
이름 : 김자바, 점수 : 100
이름 : 박자바, 점수 : 80
이름 : 최자바, 점수 : 90
이름 : 이자바, 점수 : 100
참가자 명단 : [김자바, 박자바, 최자바, 이자바]
총점 : 370
평균 : 92.5
최고점수 : 100
최저점수 : 80
import java.util.*;
public class HashMapEx3 {
static HashMap phoneBook = new HashMap();
public static void main(String[] args) {
addPhoneNo("친구", "이자바", "010-111-1111");
addPhoneNo("친구", "김자바", "010-222-2222");
addPhoneNo("친구", "김자바", "010-333-3333");
addPhoneNo("회사", "김대리", "010-444-4444");
addPhoneNo("회사", "김대리", "010-555-5555");
addPhoneNo("회사", "박대리", "010-666-6666");
addPhoneNo("회사", "이과장", "010-777-7777");
addPhoneNo("세탁", "010-888-8888");
printList();
} //main
//그룹에 전화번호를 추가하는 메서드
static void addPhoneNo (String groupName, String name, String tel){
addGroup(groupName);
HashMap group = (HashMap) phoneBook.get(groupName);
//phonebook에 저장된 키(그룹명)를 통해 값인 해쉬맵을 가져와 group에 할당
group.put(tel, name); // 이름은 중복될 수 있으니 전화번호를 key로 저장
}
static void addPhoneNo (String name, String tel){
addPhoneNo("기타", name, tel);
}
//그룹을 추가하는 메서드
static void addGroup (String groupName){
if (!phoneBook.containsKey(groupName))
phoneBook.put(groupName, new HashMap());
//Value가 Hashmap 키 = 그룹명, 값 = 해쉬맵 (키 = 전화번호, 값 = 이름)
}
static void printList () {
Set set = phoneBook.entrySet();
Iterator it = set.iterator();
while (it.hasNext()) {
Map.Entry e = (Map.Entry) it.next();
Set subSet = ((HashMap) e.getValue()).entrySet();
Iterator subIt = subSet.iterator();
System.out.println(" * " + e.getKey() + "[" + subSet.size() + "]");
while (subIt.hasNext()) {
Map.Entry subE = (Map.Entry) subIt.next();
String telNo = (String) subE.getKey();
String name = (String) subE.getValue();
System.out.println(name + " " + telNo);
}
System.out.println();
}
}
}
===========
실 행 결 과
===========
* 기타[1]
세탁 010-888-8888
* 친구[3]
이자바 010-111-1111
김자바 010-222-2222
김자바 010-333-3333
* 회사[4]
이과장 010-777-7777
김대리 010-444-4444
김대리 010-555-5555
박대리 010-666-6666
import java.util.*;
class HashMapEx4 {
public static void main(String[] args){
String[] data = {"A","K","A","K","D","K","A","K","K","K","Z","D"};
HashMap map = new HashMap();
for(int i=0; i < data.length; i++){
if(map.containsKey(data[i])) {
Integer value = (Integer)map.get(data[i]);
map.put (data[i], new Integer(value.intValue() + 1));
} else {
map.put (data[i], new Integer(1));
}
}
Iterator it = map.entrySet().iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
int value = ((Integer)entry.getValue()).intValue();
System.out.println(entry.getKey() + " : " + printBar('#',value) + " " + value);
}
} //main 끝
public static String printBar(ㅊhar ch, int value) {
char[] bar = new char[value];
for(int i=0; i < bar.length; i++)
bar[i] = ch;
return new String(bar);
}
}
===========
실 행 결 과
===========
A : ### 3
D : ## 2
Z : # 1
K : ###### 6
순차적인 값들의 빈도수는 배열을 이용하지만, 이처럼 한정되지 않은 범위의 비순차적인 값들의 빈도수는 HashMap을 이용해 구할 수 있다.
TreeMap
이진검색트리의 형태로 키와 값의 쌍으로 이루어진 데이터를 저장한다. 그래서 검색과 정렬에 적합한 컬렉션 클래스이다.
검색 : HashMap > TreeMap But. 범위검색이나 정렬이 필요한 경우에는 TreeMap을 사용하는 것이 좋다.
메서드 | 설명 |
TreeMap() | TreeMap객체를 생성 |
TreeMap(Comparator c) | 지정된 Comparator를 기준으로 정렬하는 TreeMap객체를 생성 |
TreeMap(Map m) | 주어진 |
TreeMap(SortedMap m) | |
Object put(Object key, Object value) | 지정된 키와 값을 TreeMap에 저장 |
void putAll(Map map) | Map에 저장된 모든 요소를 TreeMap에 저장 |
Object get(Object key) | 지정된 키(key)의 값(객체)을 반환 |
Obejct firstKey() | TreeMap에 저장된 첫번째(가장 작은) 키를 반환 |
Object lastKey() | TreeMap에 저장된 마지막 키(가장 큰 키)를 반환 |
Object lowerKey(Object key) | 지정된 key보다 작은 키 중에서 가장 큰 키(key)를 반환. 없으면 null을 반환 |
Object ceilingKey(Object key) | 지정된 key와 일치하거나 큰 것중 제일 작은 것의 키를 반환 없으면 null |
boolean isEmpty() | TreeMap이 비어있는지 알려준다. |
int size() | TreeMap에 저장된 요소의 개수를 반환 |
Object clone() | 현재 TreeMap을 복제해서 반환 |
void clear() | TreeMap에 저장된 모든 객체를 제거 |
Object remove(Object key) | TreeMap에서 지정된 키로 저장된 값(객체)제거 |
Object replace(Object key, Object value) | 기존의 키(key)의 값을 지정된 값(value)로 변경 |
boolean replace(Object key, Object oldValue, Object newValue) |
기존의 키(key)의 값을 새로운 값(newValue)으로 변경 단, 기존의 값과 지정된 값(oldValue)가 일치해야함 |
boolean containsKey(Object key) | TreeMap에 지정된 키(key)가 포함되어있는지 알려줌 (포함되어 있으면 true) |
boolean containsValue(Object key) | TreeMap에 지정된 값(value)가 포함되어있는지 알려줌 (포함되어 있으면 true) |
Collection valuse() | TreeMap에 저장된 모든 값을 컬렉션의 형태로 반환 |
SortedMap subMap(Object fromkey, Object toKey) |
지정된 두 개의 키 사이에 있는 모든 요소들이 담긴 SortedMap을 반환 (toKey는 포함되지 않는다.) |
NavigableMap subMap(Object fromkey, boolean fromInclusive, Object toKey, boolean toInclusive) |
지정된 두개의 키 사이에 있는 모든 요소들이 담긴 NavigableMap을 반환 fromInclusive가 true면 범위에 fromKey포함 toInclusive가 true면 범위에 tokey포함 |
SortedMap headMap(Object toKey) | TreeMap에 저장된 첫번째 요소부터 지정된 범위에 속한 모든 요소가 담긴 SortedMap을 반환 (toKey는 미포함) |
NavigableMap headMap(Object tokey, boolean inclusive) |
TreeMap에 저장된 첫번째 요소부터 지정된 범위에 속한 모든 요소가 담긴 SortedMap을 반환. inclusive의 값이 true면 tokey도 포함 |
SortedMap tailMap(Object fromKey) | 지정된 키부터 마지막 요소의 범위에 있는 요소들이 담긴 SortedMap을 반환 |
NavigableMap tailMap(Object fromKey, boolean inclusive) |
지정된 키부터 마지막 요소의 범위에 속한 요소가 담긴 NavigableMap을 반환 inclusive가 true면 fromKey도 포함 |
Set keySet() | TreeMap에 저장된 모든 키가 저장된 Set을 반환 |
Set entrySet() | TreeMap에 저장된 키와 값을 엔트리(키와 값의 결합)의 형태로 Set에 저장해서 반환 |
NavigableSet navigableKeySet() | TreeMap의 모든 키가 담긴 NavigableSet을 반환. |
Map.Entry firstEntry firstEntry() | TreeMap에 저장된 첫번째(가장 작은) 키와 값의 쌍(Map.Entry)을 반환 |
Map.Entry lastEntry() | TreeMap에 저장된 마지막 키(가장 큰 키)의 쌍(Map.Entry)을 반환 |
Map.Entry higerEntry(Object key) | 지정된 key보다 큰 키 중에서 제일 작은 키의 쌍(Map.Entry)를 반환 없으면 null을 반환 |
Map.Entry lowerEntry(Object key) | 지정된 key보다 작은 키 중에서 가장 큰 키의 쌍(Map.Entry)를 반환. 없으면 null을 반환 |
Map.Entry ceilingEntry(Object key) | 지정된 key와 일치하거나 큰 것중 제일 작은 것의 키와 값의 쌍(Map.Entry)를 반환. 없으면 null을 반환 |
Map.Entry floorEntry(Object key) | 지정된 key와 일치하거나 작은 것 중에서 가장 큰 키의 쌍(Map.Entry)를 반환. 없으면 null을 반환 |
Map.Entry pollFirstEntry() | TreeMap에서 제일 작은 키를 제거하면서 반환 |
Map.Entry pollLastEntry() | TreeMap에서 제일 큰 키를 제거하면서 반환 |
Comparator comparator() | TreeMap의 정렬기준이 되는 Comparator를 반환 Comparator가 지정되지 않았다면 null을 반환 |
NavigableSet descendingKeySet() |
TreeMap 예제
import java.util.*;
public class TreeEx1 {
public static void main(String[] args) {
String[] data = {"A", "K", "A", "K", "D", "K", "A", "K", "K", "K", "Z", "D"};
TreeMap map = new TreeMap();
for (int i = 0; i < data.length; i++) {
if (map.containsKey(data[i])) {
Integer value = (Integer) map.get(data[i]);
map.put(data[i], new Integer(value.intValue()) + 1);
} else {
map.put(data[i], new Integer(1));
}
}
Iterator it = map.entrySet().iterator();
System.out.println("= 기본정렬 = ");
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
int value = ((Integer) entry.getValue()).intValue();
System.out.println(entry.getKey() + " : " + printBar('#', value) + " " + value);
}
System.out.println();
//map을 ArrayList로 변환한 다음에 Collections.sort()로 정령
Set set = map.entrySet();
List list = new ArrayList(set); //ArrayList(Collection c)
// static void sort(List list, Comparator c)
Collections.sort(list, new ValueComparator());
it = list.iterator();
System.out.println("= 값의 크기가 큰 순서로 정렬 =");
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
int value = ((Integer) entry.getValue()).intValue();
System.out.println(entry.getKey() + " : " + printBar('#', value) + " " + value);
}
} //main의 끝
static class ValueComparator implements Comparator {
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof Map.Entry && o2 instanceof Map.Entry){
Map.Entry e1 = (Map.Entry) o1;
Map.Entry e2 = (Map.Entry) o2;
int v1 = ((Integer)e1.getValue()).intValue();
int v2 = ((Integer)e2.getValue()).intValue();
return v2 - v1;
}
return -1;
}
} // ValueComparator의 끝
public static String printBar(char ch, int value) {
char[] bar = new char[value];
for(int i=0; i < bar.length; i++)
bar[i] = ch;
return new String(bar);
}
}
==실행결과==
= 기본정렬 =
A : ### 3
D : ## 2
K : ###### 6
Z : # 1
= 값의 크기가 큰 순서로 정렬 =
K : ###### 6
A : ### 3
D : ## 2
Z : # 1
TreeMap의 예제오 달리 기본정렬에서 키가 오름차순으로 정렬돼있는 것을 알 수 있다. 키가 String 클래스이기 때문에 String클래스에 정의된 정렬기준에 의해서 정렬된 것이다.
그리고 Comparator를 구현한 클래스와 Collections.sort()이용해 내림차순으로 정렬하는 것을 보여준다.
'Java' 카테고리의 다른 글
[Java 기초 공부] 컬렉션 프레임웍 인터페이스 - 5 (0) | 2024.03.13 |
---|---|
[Java 기초 공부] 해싱과 해싱함수 (1) | 2024.03.13 |
[Java 기초 공부] 컬렉션 프레임웍 인터페이스 - 3 (Set) (0) | 2024.03.13 |
[Java 기초 공부] 컬렉션 프레임웍 인터페이스 - 2 (0) | 2024.03.11 |
[Java 기초 공부] 컬렉션 프레임웍 인터페이스 -1 (0) | 2024.01.11 |