Map (HashMap, TreeMap, LinkedHashMap) เป็นโครงสร้างข้อมูล Key-Value การวนลูปต้องพิจารณาว่าต้องการ Key, Value, หรือทั้งคู่ บทความนี้ครอบคลุม 4 วิธีหลัก
เตรียม Map ตัวอย่าง
import java.util.HashMap;
import java.util.Map;
Map<String, Integer> items = new HashMap<>();
items.put("Apple", 10);
items.put("Banana", 20);
items.put("Orange", 15);
1. entrySet() - Key และ Value พร้อมกัน (แนะนำมากที่สุด)
for (Map.Entry<String, Integer> entry : items.entrySet()) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println("Key: " + key + ", Value: " + value);
}
✅ Best Practice: ประสิทธิภาพดีที่สุดสำหรับการเข้าถึงทั้ง Key และ Value พร้อมกัน
2. keySet() - Key เท่านั้น
for (String key : items.keySet()) {
System.out.println("Key: " + key);
// ถ้าต้องการ value ต้อง items.get(key) เพิ่มอีกครั้ง (ช้ากว่า)
}
✅ ใช้เมื่อ: ต้องการแค่ Key
3. values() - Value เท่านั้น
for (Integer value : items.values()) {
System.out.println("Value: " + value);
}
✅ ใช้เมื่อ: ต้องการแค่ Value ไม่สนใจ Key
4. Iterator (Generics และ Non-Generics)
With Generics (Java 5+)
import java.util.Iterator;
import java.util.Map;
Iterator<Map.Entry<String, Integer>> iterator = items.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Integer> entry = iterator.next();
System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
// ลบข้อมูลระหว่างลูปได้
if (entry.getValue() < 15) {
iterator.remove();
}
}
Without Generics (Legacy Code)
// ไม่แนะนำสำหรับโค้ดใหม่ - มีความเสี่ยง ClassCastException
Map map = new HashMap();
Iterator entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
String key = (String) entry.getKey();
Integer value = (Integer) entry.getValue();
}
5. forEach() + Lambda - Java 8+ (Bonus)
// BiConsumer (key, value)
items.forEach((key, value) ->
System.out.println("Item: " + key + " Count: " + value)
);
// Method reference
items.forEach(System.out::println); // พิมพ์ Map.Entry ทั้งคู่
6. วน Key แล้ว Lookup Value (ไม่แนะนำ)
// ❌ ไม่แนะนำ - ทำ Hash Lookup ซ้ำ 2 ครั้ง (keySet + get)
for (String key : items.keySet()) {
Integer value = items.get(key); // O(1) แต่ทำซ้ำ
System.out.println(key + " = " + value);
}
สรุป: ประสิทธิภาพและกรณีใช้งาน
| วิธี | เหมาะสำหรับ | Performance | ลบระหว่างลูปได้? |
|---|---|---|---|
| entrySet() | Key + Value พร้อมกัน | ⭐⭐⭐⭐⭐ | ❌ (ใช้ Iterator แทน) |
| keySet() | Key เท่านั้น | ⭐⭐⭐⭐ | ❌ |
| values() | Value เท่านั้น | ⭐⭐⭐⭐ | ❌ |
| Iterator | ลบข้อมูลระหว่างลูป | ⭐⭐⭐⭐ | ✅ iterator.remove() |
| forEach() | Functional Style | ⭐⭐⭐⭐ | ❌ |
| keySet() + get() | ไม่แนะนำ | ⭐⭐ | ❌ |