⑨ HashMap과 Hashtable
- Map인터페이스 : 순서X, 중복 - 키X, 값O
- HashMap 소스 일부
public class HashMap extends AbstractMap implements Map, Cloneable, Serializable {
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의 키(key)와 값(value)
: HashMap은 키와 값을 각각 Object타입으로 저장한다. 즉 어떠한 객체나 저장할 수 있지만 키(key)는 주로 String을 대문자 또는 소문자로 통일해서 사용한다.
- 키(key) : 컬렉션 내의 키 중에서 유일해야 한다.
- 값(value) : 키와 달리 데이터의 중복을 허용한다.
→ 키(key)는 저장된 값을 찾는데 사용되는 것이기 때문에 컬렉션 내에서 유일해야 한다. 즉 HashMap에 저장된 데이터를 하나의 키로 검색했을 때 결과가 단 하나이어야 한다.
- 해싱
- 환자정보관리.
- 해시함수로 해시테이블(배열+링크드리스트)에 데이터를 저장, 검색
- 해시테이블에 저장된 데이터를 가져오는 과정.
→ 해시함수는 같은 키에 대해 항상 같은 값의 해시코드를 반환할 수 있다.
생성자/메서드 | 설명 |
HashMap() | HashMap객체를 생성 |
HashMap(int initialCapacity) | 지정된 값을 초기용량으로 하는 HashMap객체를 생성 |
HashMap(int initialCapacity, float loadFactor) | 지정된 초기용량과 load factor의 HashMap객체를 생성 |
HashMap(Map m) | 지정된 Map의 모든 요소를 포함하는 HashMap을 생성 |
void clear() | HashMap에 저장된 모든 객체를 제거 |
Object clone() | 현재 HashMap을 복제해서 반환 |
boolean containsKey(Object key) | HashMap에 지정된 키(key)가 포함되어있는지 알려준다. (포함되어 있으면 true) |
boolean containsValue(Object value) | HashMap에 저장된 키와 값을 엔트리(키와 값의 결합)의 형태로 Set에 저장해서 반환 |
Set entrySet() | 지정된 키와 값을 반환. 못찾으면 null 반환 |
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) | 지정된 키와 객체가 모두 일치하는 경우에만 새로운 객체로 대체 |
int size() | HashMap에 저장된 요소의 개수를 반환 |
Collection values() | HashMap에 저장된 모든 값을 컬렉션의 형태로 반환 |
- HashMap 예제1
import java.util.*;
class JavaJungsuk_CollectionFramework_HashMap_1 {
public static void main(String[] args) {
HashMap map=new HashMap();
map.put("myId", "1234");
map.put("asdf", "1111");
map.put("asdf", "1234");
Scanner scn=new Scanner(System.in);
while(true) {
System.out.println("id와 password를 입력해주세요.");
System.out.print("id :");
String id=scn.nextLine().trim();
System.out.print("password :");
String password=scn.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;
}
}
}
}
결과
id와 password를 입력해주세요.
id :asdf
password :1111
비밀번호가 일치하지 않습니다. 다시 입력해주세요.
id와 password를 입력해주세요.
id :asdf
password :1234
id와 비밀번호가 일치합니다.
→ HashMap을 생성하고 키와 값을 쌍으로 저장한 다음 사용자 Id를 키로 HashMap에서 검색해서 얻은 값(password)을 입력된 password와 비교하는 예제이다.
→ HashMap을 생성하고 데이터를 저장하면 HashMap에는 위와 같은 형태로 데이터가 저장된다.
→ 3개의 데이터 쌍을 저장했지만 실제로 2개 밖에 저장되지 않은 이유는 중복된 키가 있기 때문이다. 그래서 세번째로 저장한 데이터의 키인 'asdf'는 이미 존재하기 때문에 서로 추가되는 대신 기존의 값을 덮어썼다.
그래서 키 'asdf'에 연결된 값은 '1234'가 된다.
- HashMap 예제2
import java.util.*;
class JavaJungsuk_CollectionFramework_HashMap_2 {
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])) {
int value=(int)map.get(data[i]);
map.put(data[i], value+1);
} else {
map.put(data[i], 1);
}
}
Iterator it=map.entrySet().iterator();
while(it.hasNext()) {
Map.Entry entry=(Map.Entry)it.next();
int value=(int)entry.getValue();
System.out.println(entry.getKey()+" : "+printBar('#', value)+" "+value);
}
}
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
Z : # 1
K : ###### 6
→ containsKey()로 같은 문자열이 저장되어 있는지 확인하여 이미 저장되어 있는 문자열이면 값을 1 증가시킨다.
→ 그 결과를 printBar()를 이용해서 출력하도록 하였다.
→ 이처럼 한정되지 않은 범위의 비순차적인 값들의 빈도수는 HashMap을 이용해서 구할 수 있다.
'프로그래밍 > Java' 카테고리의 다른 글
Java_제네릭스·지네릭스(1)_타입 변수, 제네릭스 용어, 제네릭의 타입과 다형성, Iterator<E>, HashMap<K,V>, 제한된 제네릭 클래스 (0) | 2023.01.15 |
---|---|
Java_컬렉션프레임웍(7)_Collections의 메서드(동기화, 변경불가, 싱글톤, 단일 컬렉션), 컬렉션 클래스 정리 (0) | 2023.01.11 |
Java_컬렉션프레임웍(5)_TreeSet (0) | 2023.01.04 |
Java_컬렉션 프레임웍(4)_Comparator와 Comparable, HashSet (0) | 2023.01.01 |
Java_컬렉션 프레임웍(3)_Iterator, ListIterator, Enumeration, Map과 Iterator, Arrays의 메서드 (0) | 2022.12.28 |