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

Java Program เรียงลำดับ Map ตาม Value (Sort Map by Values)

การเรียงลำดับ Map ตาม Value

HashMap ไม่รักษาลำดับ (Unordered) เพื่อเรียงตาม Value ต้องแปลงเป็น List ของ Entries เรียง แล้วสร้าง Map ใหม่ที่รักษาลำดับ (LinkedHashMap)

ขั้นตอน

  1. แปลง entrySet() เป็น List<Map.Entry>
  2. เรียง List ด้วย Comparator เปรียบเทียบ Value
  3. สร้าง 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 เพื่อรักษาลำดับหลังเรียง