Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

Java Program หา Key จาก HashMap โดยใช้ Value (Reverse Lookup)

ปัญหา: หา 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