: 키(key)와 값(value)으로 구성된 Map.Entry 객체를 저장하는 구조를 가지고 있음
: Entry는 Map 인터페이스 내부에 선언된 중첩 인터페이스임
여기서 키와 값은 모두 객체임
: 키는 중복 저장될 수 없지만 값은 중복 저장될 수 있음
만약 기존에 저장된 키와 동일한 키로 값을 저장하면
기존의 값은 없어지고 새로운 값으로 대체됨
: Map 컬렉션에는
HashMap, Hashtable, LinkedHashMap, Properties, TreeMap 등이 있음
: 키로 객체들을 관리히기 때문에 키를 매개값으로 갖는 메소드가 많음
: 메소드의 매개 변수 타입과 리턴 타입에 K와 V라는 타입 파라미터는
저장되는 키와 객체의 타입을 Map 컬렉션을 생성할 때 결정하라는 뜻
ex)
키 타입이 String, 값 타입이 Integer인 Map 컬렉션을 생성하고,
put()메소드로 키와 값을 저장함
그리고 키로 값을 얻거나 제거하기 위해
get()과 remove() 메소드를 사용함
Map<String, Integer> map = ···;
map.put("홍길동", 30);
int score = map.get("홍길동");
map.remove("홍길동");
: Map<String, Integer>로 map 변수를 선언
이것은 Map 컬렉션에 저장되는 키 객체는 String 타입으로,
값 객체는 Integer 타입으로 하겠다는 뜻
따라서 K 타입 파라미터는 String이 되고,
V 타입 파라미터는 Integer가 되는 것
그래서 put() 메소드의 첫 번째 매개 값은 문자열이고,
두 번째 매개값은 30이 포장된 Integer 객체(자동 박싱)가 됨
- 저장된 전체 객체를 대상으로 하나씩 얻고 싶을 경우
1) keySet() 메소드로 모든 키를 Set 컬렉션으로 얻은 다음,
반복자를 통해 키를 하나씩 얻고 get() 메소드를 통해 값을 얻는 방법
Map<K, V> map = ···;
Set<K> keySet = map.keySet();
Iterator<K> keyIterator = keySet.iterator();
while(keyIterator.hasNext()) {
K key = keyIterator.next();
V value = map.get(key);
}
2) entrySet() 메소드로 모든 Map.Entry를 Set 컬렉션으로 얻은 다음,
반복자를 통해 Map.Entry를 하나씩 얻고
getKey()와 getValue() 메소드를 이용해 키와 값을 얻는 방법
Set<Map.Entry<K,V>> entrySet = map.entrySet();
Iterator<Map.Entry<K, V>> entryIterator = entrySet.iterator();
while(entryIterator.hasNext()) {
Map.Entry<K, V> entry = entryIterator.next();
K key = entry.getKey();
V value = entry.getValue();
}
: Map 인터페이스를 구현한 대표적은 Map 컬렉션
: HashMap의 키로 사용할 객체는
hashCode()와 equals() 메소드를 재정의해서
동등 객체가 될 조건을 정해야함
: 객체가 달라도 동등 객체라면 같은 키로 간주하고
중복 저장되지 않도록 하기 위함
: 동등 객체의 조건은 hashCode()의 리턴값이 같아야 하고,
equalsd() 메소드가 true를 리턴해야함
: 주로 키 타입은 String을 많이 사용하는데,
String은 문자열이 같을 경우 동등 객체가 될 수 있도록
hashCode()와 equals() 메소드가 재정의되어 있음
- HashMap 생성
Map<K, V> amp = new HasMap<K, V>();
키 타입과 값 타입을 타입 파라미터로 주고 기본 생성자를 호출하면됨
: 키와 값의 타입은
기본 타입(byte, short, int, float, double, boolean, char)을 사용할 수 없고
클래스 및 인터페이스 타입만 사용 가능함
ex) 키로 String 타입을 사용하고 값으로 Integer 타입을 사용시 HashMap 생성
Map<String, Integer> map = new HashMap<String, Integer>();
Map<String, Integer> map = new HashMap<>();
👩💻 이름을 키로 점수를 값으로 저장하기
import java.util.*;
public class HashMapExample {
public static void main(String[] args) {
//Map 컬렉션 생성
Map<String, Integer> map = new HashMap<String, Integer>();
//객체 저장
//홍길동2는 키가 같기 떄문에 마지막 저장 값으로 대체
map.put("홍길동1", 85);
map.put("홍길동2", 90);
map.put("홍길동3", 80);
map.put("홍길동2", 95);
System.out.println("총 Entry 수: " + map.size());
//객체 찾기
//이름(키)으로 점수(값)를 검색
System.out.println("\t홍길동2: " + map.get("홍길동2"));
System.out.println();
//객체를 하나씩 처리
Set<String> keySet = map.keySet();
Iterator<String> keyIterator = keySet.iterator();
while(keyIterator.hasNext()) {
String key = keyIterator.next();
Integer value = map.get(key);
System.out.println("\t" + key + ": " + value);
}
System.out.println();
//객체 삭제
map.remove("홍길동2");
System.out.println("총 Entry 수: " + map.size());
//객체를 하나씩 처리
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
Iterator<Map.Entry<String, Integer>> entryIterator =
entrySet.iterator();
while(entryIterator.hasNext()) {
Map.Entry<String, Integer> entry = entryIterator.next();
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println("\t" + key + ": " + value);
}
System.out.println();
//객체 전체 삭제
map.clear();
System.out.println("총 Entry 수: " + map.size());
}
}
💻 결과
총 Entry 수: 3
홍길동2: 95
홍길동2: 95
홍길동3: 80
홍길동1: 85
총 Entry 수: 2
홍길동3: 80
홍길동1: 85
총 Entry 수: 0
// 키로 사용할 객체
// hashCode()와 equals() 재정의
class Student {
public int sno;
public String name;
public Student(int sno, String name) {
this.sno = sno;
this.name = name;
}
public boolean equals(Object obj) {
if(obj instanceof Student) {
Student student = (Student) obj;
return (sno == student.sno) && (name.equals(student.name));
} else {
return false;
}
}
public int hashCode() {
return sno + name.hashCode();
}
}
// 학번과 이름이 동일한 경우 같은 키로 인식
public class HashMapExample2 {
public static void main(String[] args) {
Map<Student, Integer> map = new HashMap<Student, Integer>();
map.put(new Student(1, "홍길동"), 95);
map.put(new Student(1, "홍길동"), 95);
System.out.println("총 Entry 수: " + map.size());
}
}
💻 결과
총 Entry 수: 1
: HashMap과 동일한 내부 구조를 가짐
: 키로 사용할 객체는 hashCode()와 equals() 메소드를
재정의해서 동등 객체가 될 조건을 정해야함
: HashMap과 차이점은
Hashtable은 동기화된 메소드로 구성되어 있기 때문에
멀티 스레드가 동시에 Hashtable의 메소드들을 실행할 수 없고,
하나의 스레드가 실행을 완료해야만 다른 스레드를 실행할 수 있다는 것
그래서 멀티 스레드 환경에서 안전하게 객체를 추가, 삭제할 수 있기 때문에
Hashtable은 스레드에 안전함
- 생성방법
Map<K, V> map = new Hashtable<K, V>();
-방법
ex) 키로 String 타입을 사용하고, 값으로 Integer 타입을 사용하는 Hashtable 생성
Map<String, Integer> map = new Hashtable<String, Integer>();
Map<String, Integer> map = new Hashtable<>();
👩💻 아이디와 비밀번호 검사하기
import java.util.*;
public class HashTableExample {
public static void main(String[] args) {
Map<String, String> map = new Hashtable<String, String>();
map.put("spring", "12");
map.put("summer", "123");
map.put("fall", "1234");
map.put("winter", "12345");
Scanner scanner = new Scanner(System.in);
while(true) {
System.out.println("아이디와 비밀번호르 입력해주세요.");
System.out.println("아이디: ");
String id = scanner.nextLine();
System.out.println("비밀번호: ");
String password = scanner.nextLine();
System.out.println();
if(map.containsKey(id)) {
if(map.get(id).equals(password)) {
System.out.println("로그인되었습니다.");
break;
}else {
System.out.println("비밀번호가 일치하지 않습니다.");
}
} else {
System.out.println("입력하신 아이디가 존재하지 않습니다.");
}
}
}
}
💻 결과
아이디와 비밀번호르 입력해주세요.
아이디:
summer
비밀번호:
123
로그인되었습니다.