ปัญหา: หา Key จาก Value ใน HashMap
HashMap<K, V> ออกแบบมาสำหรับค้นหา Value จาก Key (O(1)) แต่ไม่มีเมธอด built-in สำหรับหา Key จาก Value เพราะ Value อาจซ้ำได้ (Non-unique)
วิธีการ: Iterate + Compare
ต้องวนลูปผ่าน entrySet() เปรียบเทียบ Value แต่ละคู่กับค่าที่ต้องการ
ตัวอย่างที่ 1: ใน main โดยตรง
import java.util.HashMap;
import java.util.Map.Entry;
public class Demo {
public static void main(String[] args) {
System.out.println("The required packages have been imported");
HashMap inputMap = new HashMap<>();
inputMap.put("Scala", 5);
inputMap.put("Java", 8);
inputMap.put("Python", 15);
System.out.println("The HashMap is defined as: " + inputMap);
Integer key = 8; // ค่าที่ต้องการหา Key
for (Entry entry : inputMap.entrySet()) {
if (entry.getValue().equals(key)) {
System.out.println("\nThe value of Key: " + key + " is " + entry.getKey());
break; // หเจอแล้วหยุด (สมมติ Value unique)
}
}
}
}
ผลลัพธ์
The required packages have been imported
The HashMap is defined as: {Java=8, Scala=5, Python=15}
The value of Key: 8 is Java
ตัวอย่างที่ 2: แยกเป็นเมธอด (OOP)
import java.util.HashMap;
import java.util.Map.Entry;
public class Demo {
static void getValue(HashMap inputMap, Integer key) {
for (Entry entry : inputMap.entrySet()) {
if (entry.getValue().equals(key)) {
System.out.println("\nThe value of Key: " + key + " is " + entry.getKey());
break;
}
}
}
public static void main(String[] args) {
System.out.println("The required packages have been imported");
HashMap inputMap = new HashMap<>();
inputMap.put("Scala", 5);
inputMap.put("Java", 8);
inputMap.put("Python", 15);
System.out.println("The HashMap is defined as: " + inputMap);
Integer key = 8;
getValue(inputMap, key);
}
}
กรณี Value ซ้ำกัน (Duplicate Values)
หาก Value ซ้ำกัน อาจต้องการ Key ทั้งหมด:
public static List getKeysByValue(HashMap map, Integer targetValue) {
List keys = new ArrayList<>();
for (Entry entry : map.entrySet()) {
if (entry.getValue().equals(targetValue)) {
keys.add(entry.getKey());
}
}
return keys;
}
// ใช้งาน
HashMap map = new HashMap<>();
map.put("A", 10);
map.put("B", 20);
map.put("C", 10); // Duplicate value
List keys = getKeysByValue(map, 10);
System.out.println(keys); // [A, C]
วิธีอื่น: ใช้ BiMap (Guava Library)
หากต้องการ Reverse Lookup บ่อย ควรใช้ BiMap จาก Google Guava:
// Dependency: com.google.guava:guava:32.x
import com.google.common.collect.HashBiMap;
import com.google.common.collect.BiMap;
BiMap biMap = HashBiMap.create();
biMap.put("Java", 8);
biMap.put("Scala", 5);
biMap.put("Python", 15);
// Lookup ทั้งสองทาง O(1)
String key = biMap.inverse().get(8); // "Java"
Integer value = biMap.get("Java"); // 8
// BiMap บังคับ Value unique (throw exception ถ้าซ้ำ)
Java 8+ Stream API Approach
// หา Key แรกที่ match (Optional)
String key = inputMap.entrySet().stream()
.filter(e -> e.getValue().equals(8))
.map(Entry::getKey)
.findFirst()
.orElse(null);
// หา Key ทั้งหมดที่ match
List keys = inputMap.entrySet().stream()
.filter(e -> e.getValue().equals(8))
.map(Entry::getKey)
.collect(Collectors.toList());
ประสิทธิภาพ (Performance)
| วิธีการ | Time Complexity | Space | เหมาะสำหรับ |
|---|---|---|---|
| Iterate entrySet() | O(n) | O(1) | Lookup ครั้งคราว, Map ขนาดเล็ก |
| Stream API | O(n) | O(1) / O(k) | Code เรียบร้อย, Functional style |
| BiMap (Guava) | O(1) | O(n) | Reverse lookup บ่อย, Value unique |
| Maintain 2 Maps | O(1) | O(n) | ควบคุมเองได้ ไม่ต้อง library |
สรุป
- HashMap ไม่มี reverse lookup built-in
- ใช้
entrySet()วนลูปเปรียบเทียบ Value - ใช้
equals()เปรียบเทียบ Object (ไม่ใช่ ==) - หาก Value ซ้ำ ตัดสินใจว่าจะคืน Key แรก หรือ Key ทั้งหมด
- หาก Reverse Lookup บ่อย → ใช้ BiMap (Guava) หรือ Maintain 2 Maps