
HashMap
TreeMap
LinkedHashMap
HashTable
| 기능 | HashMap | HashTable |
|---|---|---|
| key, value에 null 저장 가능 여부 | 가능 | 불가능 |
| Thread-safe | Not Safe | Safe |
| 데이터 처리 | Collection View | Enumeration 객체 |
Map m = Collection.synchronizedMap(new HashMap(…));keySet(), values(), entrySet() 등의 메소드를 통해 Map의 내용을 Collection View 형태로 볼 수 있음keySet(): Map의 모든 키를 Set 객체로 반환values(): Map의 모든 값을 Collection 객체로 반환entrySet(): Map의 모든 key-value 쌍을 Entry 객체의 Set으로 반환import java.util.HashMap;
import java.util.Map;
public class HashMapExample {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("One", 1);
map.put("Two", 2);
map.put("Three", 3);
// Collection View를 사용한 반복
for (Map.**Entry<String, Integer>** entry : map.**entrySet()**) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
}
keys() 메소드는 Map의 키에 대한 Enumeration을 반환하고, elements() 메소드는 값에 대한 Enumeration을 반환Enumeration은 Iterator의 구식 버전keys(): Map의 모든 키에 대한 Enumeration 객체를 반환합니다.elements(): Map의 모든 값에 대한 Enumeration 객체를 반환합니다import java.util.Hashtable;
import java.util.Enumeration;
public class HashtableExample {
public static void main(String[] args) {
Hashtable<String, Integer> table = new Hashtable<>();
table.put("One", 1);
table.put("Two", 2);
table.put("Three", 3);
// Enumeration을 사용한 키 반복
**Enumeration<String> keys = table.keys();**
while (**keys.hasMoreElements()**) {
String key = keys.**nextElement()**;
System.out.println(key + " = " + table.get(key));
}
}
}
java.util.Objectjava.util.AbstractMap<K, V>java.util.HashMap<K, V>AbstractMap 클래스가 구현함Object클래스의 hashcode(), equals() 메소드 잘 구현해야 함HashMap에 객체가 들어가면 그 객체의 hashcode() 결과 값에 따라 bucket이 만들어짐hashcode() 결과 값이 동일하면 같은 bucket에 여러 개의 값이 들어갈 수 있음(=충돌)get() 호출 시, hashcode() 결과 확인 후, bucket에 여러 개 data 존재할 경우 equals()로 동일한 값을 찾게 된다import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
class Book {
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Book book = (Book) o;
return Objects.equals(title, book.title) &&
Objects.equals(author, book.author);
}
@Override
public int hashCode() {
return Objects.hash(title, author);
}
}
public class HashMapExample {
public static void main(String[] args) {
Map<Book, Integer> books = new HashMap<>();
Book book1 = new Book("Effective Java", "Joshua Bloch");
Book book2 = new Book("Java Concurrency in Practice", "Brian Goetz");
books.put(book1, 1);
books.put(book2, 2);
// 동일한 속성을 가진 새 객체를 생성
Book book3 = new Book("Effective Java", "Joshua Bloch");
// book3는 book1과 같은 속성을 가지므로, 같은 hashCode를 가질 것이고 equals()에서 true를 반환할 것이다.
System.out.println("Book1's hashcode: " + book1.hashCode());
System.out.println("Book3's hashcode: " + book3.hashCode());
System.out.println("Book1 and Book3 are equal: " + book1.equals(book3));
System.out.println("Number of copies of 'Effective Java': " + books.get(book3));
}
}
Book 클래스는 title과 author 필드를 기반으로 hashCode()와 equals() 메소드를 재정의Book 객체들은 동일한 해시코드 → equals() 메소드에서 true를 반환함book1과 book3이 같은 속성book3을 사용하여 book1을 키로 가지는 값을 성공적으로 검색 가능hashcode()와 equals() 구현해라**null**을 반환해버린다Set, Map 자료 구조는 순서가 중요하지 않다**keySet()**을 통해 해당 hashMap에 어떤 key들이 있는지 알 수 있음SetSet의 제네릭 타입은 선언한 HashMap의 Key의 제네릭 타입HashMap<**String**, Integer> map = new HashMap<>();**Set<String>** keySet = map.**keySet()**;**values()**을 통해 해당 hashMap에 어떤 value들이 있는지 알 수 있음CollectionHashMap<String, **Integer**> map = new HashMap<>();**Collection<Integer>** values = map.**values()**;**entrySet()**을 통해 Key와 Value를 세트로 알 수 있다Set<Map.Entry<>>Set타입으로 리턴, Set내에는 Entry타입으로 데이터가 저장되어 있음HashMap<String, Integer> map = new HashMap<>();Set<**Map.Entry<String, Integer>**> entries = new map.entrySet();containsKey(obj), containsValue(obj)containsKey()를 써야될까?get(obj) == null방식으로도 확인 가능한데 왜 containsKey()를 쓰는게 효과적일까?HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("1", null);
if (hashMap.get("1") == null) {
System.out.println(hashMap.get("1"));
}
1 에 대한 value에 명시적으로 null이 저장되어 있다면 **hashMap.get("1") == null 이 구문은 true가 된다**1 인게 있는지 없는지 여부containsKey() 쓰는게 좋다firstKey() : 가장 앞에 있는 Key
lastKey() : 가장 뒤에 있는 Key
higherKey(K key) : 특정 Key 바로 뒤에 있는 Key
lowerKey(K key) : 특정 Key 바로 앞에 있는 Key
⚠️ 이 메서드들 쓰려면 Map 인터페이스로 UpCasting하면 안된다 ⚠️
~~Map<String, Integer> map = new TreeMap<>();
String firstKey = map.firstKey():~~
**TreeMap**<String, Integer> treeMap = new TreeMap<>();
String firstKey = map.firstKey():
HashTable을 extends 했기에 Map 인터페이스에서 제공하는 모든 메서드 사용 가능Properties prop = System.getProperties();System 클래스에 static메서드인 getProperties() 호출하면 Properties객체 리턴Properties클래스 사용하는 이유는?!Properties에서 추가로 제공하는 메서드들 때문에load(), store(), storeToXML() …CollectionList : 배열처럼 목록 처리ArrayListLinkedListSet : 중복 X, 순서 XHashSetLinkedHashSetTreeSetQueue : 들어온 순서대로 처리(FIFO)LinkedListPriorityQueueMap : Key-Value 형식으로 저장HashMap : 가장 많이 씀LinkedHashMapTreeMapketSet()으로 Set타입의 key목록 리턴valuse()로 Collection타입의 valuse 목록 리턴for loop OR Iterator로 데이터 처리package second_chapter06_map;
import java.util.Hashtable;
import java.util.Random;
import java.util.Set;
public class RandomNumberStatistics {
public static void main(String[] args) {
RandomNumberStatistics sample = new RandomNumberStatistics();
sample.getRandomNumberStatistics();
}
private final int DATA_BOUNDARY = 50;
Hashtable<Integer, Integer> hashtable = new Hashtable<>();
public void getRandomNumberStatistics() {
for (int i = 0; i < 5000; i++) {
Random random = new Random();
putCurrentNumber(random.nextInt(1, DATA_BOUNDARY+1));
}
printStatistics();
}
public void putCurrentNumber(int tempNumber) {
if (hashtable.containsKey(tempNumber)) {
hashtable.put(tempNumber, hashtable.get(tempNumber)+1);
}
else {
hashtable.put(tempNumber, 1);
}
}
public void printStatistics() {
Set<Integer> keySet = hashtable.keySet();
for (int key:keySet) {
System.out.print(key + "=" + hashtable.get(key) + "\t");
// key가 1로 끝날 때마다 줄바꿈 넣자 -> 그래야 한 줄에 10개씩 이쁘게 출력
if (key%10-1==0) System.out.println();
}
}
}
Key와 Value로 구성put()get()remove()keySet()size()HashMapHashTablecontainsKey()TreeMapHashTablestore(), storeToXML() 메서드 사용