การเรียงลำดับ Map ตาม Value
HashMap ไม่รักษาลำดับ (Unordered) เพื่อเรียงตาม Value ต้องแปลงเป็น List ของ Entries เรียง แล้วสร้าง Map ใหม่ที่รักษาลำดับ (LinkedHashMap)
ขั้นตอน
- แปลง
entrySet()เป็นList<Map.Entry> - เรียง List ด้วย
Comparatorเปรียบเทียบ Value - สร้าง
LinkedHashMapใหม่ ใส่ Entry ตามลำดับที่เรียงแล้ว
ตัวอย่างที่ 1: แยกเป็นเมธอด Static
import java.util.*;
public class Demo {
public static HashMap sortByValue(HashMap inputMap) {
// 1. แปลง EntrySet เป็น List
List> list =
new LinkedList<>(inputMap.entrySet());
// 2. เรียง List ตาม Value (Comparator)
Collections.sort(list, new Comparator>() {
@Override
public int compare(Map.Entry o1,
Map.Entry o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
// 3. สร้าง LinkedHashMap ใหม่ (รักษาลำดับ)
HashMap sortedMap = new LinkedHashMap<>();
for (Map.Entry entry : list) {
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}
public static void main(String[] args) {
HashMap inputMap = new HashMap<>();
inputMap.put("Java", 45);
inputMap.put("Scala", 20);
inputMap.put("Mysql", 11);
inputMap.put("Python", 75);
System.out.println("The HashMap is defined as:");
for (Map.Entry e : inputMap.entrySet()) {
System.out.println("Key = " + e.getKey() + ", Value = " + e.getValue());
}
Map resultMap = sortByValue(inputMap);
System.out.println("\nThe HashMap after sorting is:");
for (Map.Entry e : resultMap.entrySet()) {
System.out.println("Key = " + e.getKey() + ", Value = " + e.getValue());
}
}
}
ผลลัพธ์
The HashMap is defined as:
Key = Java, Value = 45
Key = Scala, Value = 20
Key = Mysql, Value = 11
Key = Python, Value = 75
The HashMap after sorting is:
Key = Mysql, Value = 11
Key = Scala, Value = 20
Key = Java, Value = 45
Key = Python, Value = 75
ตัวอย่างที่ 2: Java 8+ Stream API (Modern)
import java.util.*;
import java.util.stream.Collectors;
public class Demo {
public static void main(String[] args) {
HashMap inputMap = new HashMap<>();
inputMap.put("Java", 45);
inputMap.put("Scala", 20);
inputMap.put("Mysql", 11);
inputMap.put("Python", 75);
System.out.println("The HashMap is defined as:");
inputMap.forEach((k, v) -> System.out.println("Key = " + k + ", Value = " + v));
// Stream API: EntrySet → Stream → Sorted → Collect to LinkedHashMap
Map sortedMap = inputMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue()) // เรียงตาม Value ASC
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1, // Merge function (ไม่ควรเกิดกับ Key Unique)
LinkedHashMap::new // รักษาลำดับ
));
System.out.println("\nThe HashMap after sorting is:");
sortedMap.forEach((k, v) -> System.out.println("Key = " + k + ", Value = " + v));
}
}
Stream API Variations
Descending Order (มากไปน้อย)
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
Null-safe Values
.sorted(Map.Entry.comparingByValue(Comparator.nullsFirst(Comparator.naturalOrder())))
Custom Comparator (เช่น String Length)
Map map = new HashMap<>();
map.put("A", "Apple");
map.put("B", "Banana");
map.put("C", "Cat");
Map sorted = map.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.comparingInt(String::length)))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
// C (3), A (5), B (6)
SortedMap Alternatives (Auto-sorted)
หากต้องการ Map ที่เรียงลำดับอัตโนมัติตลอด:
| Class | Sort By | Null Keys | Thread-Safe |
|---|---|---|---|
| TreeMap | Key (Natural/Comparator) | ❌ | ❌ |
| ConcurrentSkipListMap | Key | ❌ | ✅ |
หมายเหตุ: ไม่มี Built-in SortedMap ที่เรียงตาม Value ได้ ต้องทำเองเหมือนด้านบน
Performance Comparison
| Method | Time | Space | Code Style |
|---|---|---|---|
| Collections.sort + LinkedHashMap | O(n log n) | O(n) | Verbose (Pre-Java 8) |
| Stream API + Collectors | O(n log n) | O(n) | ⭐ Clean, Functional, Modern |
Common Pitfalls
// ❌ ผิด: ใส่กลับ HashMap (ไม่รักษาลำดับ)
Map wrong = new HashMap<>();
for (Entry e : sortedList) wrong.put(e.getKey(), e.getValue());
// ผลลัพธ์: ไม่เรียง!
// ✅ ถูก: ใช้ LinkedHashMap
Map correct = new LinkedHashMap<>();
for (Entry e : sortedList) correct.put(e.getKey(), e.getValue());
// ผลลัพธ์: เรียงตาม Value
สรุป
- HashMap ไม่รักษาลำดับ → ต้องแปลงเป็น List เรียง → สร้าง LinkedHashMap
- Java 8+: ใช้ Stream API + Collectors.toMap(LinkedHashMap::new) สะดวกที่สุด
Map.Entry.comparingByValue()สำหรับ Comparator เปรียบเทียบ Value- Descending:
Comparator.reverseOrder() - ต้องใช้ LinkedHashMap เพื่อรักษาลำดับหลังเรียง