[Java] Sắp xếp HashMap dựa trên Key và Value

Các entry trong HashMap không được sắp xếp theo thứ tự. Nhưng nếu bạn bị yêu cầu phải sắp xếp thì bạn hoàn toàn có thể làm được.

1. Sắp xếp HashMap dựa trên Key

Sắp xếp HashMap dựa trên các Keys khá là dễ. Chúng ta có 2 cách làm.

Cách 1: Dùng TreeMap (ưu tiên dùng cách này)

Việc bạn cần làm là tạo ra một TreeMap bằng cách sao chép các entries từ HashMap.

TreeMap là một implementation của SortedMap. Vì vậy nó sẽ sắp xếp theo natural ordering hoặc bạn hoàn toàn có thể custom việc sắp xếp theo ý bạn bằng cách dùng Comparator.

Cách 2: Dùng LinkedHashMap

Cách này hơi dài dòng chút. Đầu tiên bạn cần lấy ra một Set các keys. Convert Set đó thành List. Sắp xếp List đó, và rồi add chúng lại LinkedHashMap theo đúng thứ tự đã sắp xếp.

2. Sắp xếp HashMap dựa trên Value

Sắp xếp dựa trên Value khá phức tạp vì không có phương pháp trực tiếp hỗ trợ việc này. Bạn buộc phải viết code cho nó. Đầu tiên bạn phải tạo ra một Comparator để so sánh hai entries dựa trên value. Sau đó lấy Set of entries từ Map, convert Set thành List và dùng phương thức Collections.sort(List) để sắp xếp List các entries bằng value bằng cách truyền vào customized value comparator. Việc này tương tự như Làm thế nào để sắp xếp một ArrayList trong Java?

Cuối cùng, chúng ta tạo ra một LinkedHashMap, đây là một lớp extend từ HashMap và add các entries đã được sắp xếp vào đó. LinkedHashMap sẽ đảm bảo các phần tử được chèn vào theo một thứ tự 😉

Nói ngắn gọn lại: Bởi vì khác với key, thì value có thể chứa các giá trị trùng
lặp nên bạn không thể dùng TreeMap để sắp xếp giống như sắp xếp dựa trên key.

Các bước như sau:

  1. Get all entries by calling entrySet() method of Map
  2. Create a custom Comparator to sort entries based upon values
  3. Convert entry set to list
  4. Sort entry list by using Collections.sort() method by passing your value comparator
  5. Create a LinkedHashMap by adding entries in sorted order.

3. Ví dụ

3.1. Sắp xếp theo key

package com.icancodeit.java.collection;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * Sắp xếp theo Key
 */
public class HashMapSorting {

  public static void main(String[] args) {
    HashMap<String, String> map = new HashMap<String, String>();
    map.put("JDK 1.1.4", "Sparkler"); 
    map.put("J2SE 1.2", "Playground"); 
    map.put("J2SE 1.3", "Kestrel"); 
    map.put("J2SE 1.4", "Merlin"); 
    map.put("J2SE 5.0", "Tiger"); 
    map.put("Java SE 6", "Mustang"); 
    map.put("Java SE 7", "Dolphin");
    
    System.out.println("----- Before sorting, random order -----");
    Set<Map.Entry<String, String>> entries = map.entrySet();
    for (Map.Entry<String, String> entry : entries) {
      System.out.println(entry.getKey() + " ==>> " + entry.getValue());
    }
    
    // Sắp xếp HashMap dựa trên Key sử dụng TreeMap
    System.out.println("----- After sorting by keys, ascending order -----");
    TreeMap<String, String> sorted = new TreeMap<String, String>(map);
    Set<Map.Entry<String, String>> mappings = sorted.entrySet();
    for (Map.Entry<String, String> mapping : mappings) {
      System.out.println(mapping.getKey() + " ==>> " + mapping.getValue());
    }
  }

}

Output:

----- Before sorting, random order -----
J2SE 1.2 ==>> Playground
JDK 1.1.4 ==>> Sparkler
J2SE 1.3 ==>> Kestrel
J2SE 1.4 ==>> Merlin
J2SE 5.0 ==>> Tiger
Java SE 7 ==>> Dolphin
Java SE 6 ==>> Mustang

----- After sorting by keys, ascending order -----
J2SE 1.2 ==>> Playground
J2SE 1.3 ==>> Kestrel
J2SE 1.4 ==>> Merlin
J2SE 5.0 ==>> Tiger
JDK 1.1.4 ==>> Sparkler
Java SE 6 ==>> Mustang
Java SE 7 ==>> Dolphin

3.2. Sắp xếp theo value

package com.icancodeit.java.collection;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

/**
 * Sắp xếp theo Key
 */
public class HashMapSorting {

  public static void main(String[] args) {
    HashMap<String, String> map = new HashMap<String, String>();
    map.put("JDK 1.1.4", "Sparkler"); 
    map.put("J2SE 1.2", "Playground"); 
    map.put("J2SE 1.3", "Kestrel"); 
    map.put("J2SE 1.4", "Merlin"); 
    map.put("J2SE 5.0", "Tiger"); 
    map.put("Java SE 6", "Mustang"); 
    map.put("Java SE 7", "Dolphin");

    // Khởi tạo ra một Set entries
    Set<Entry<String, String>> entries = map.entrySet();

    System.out.println("----- Before sorting, random order -----");
    for (Entry<String, String> entry : entries) {
      System.out.println(entry.getKey() + " ==>> " + entry.getValue());
    }

    // Tạo custom Comparator
    Comparator<Entry<String, String>> comparator = new Comparator<Entry<String, String>>() {
      @Override
      public int compare(Entry<String, String> e1, Entry<String, String> e2) {
        String v1 = e1.getValue();
        String v2 = e2.getValue();
        return v1.compareTo(v2);
      }
    };

    // Convert Set thành List
    List<Entry<String, String>> listEntries = new ArrayList<>(entries);

    // Sắp xếp List
    Collections.sort(listEntries, comparator);

    // Tạo một LinkedHashMap và put các entry từ List đã sắp xếp sang
    LinkedHashMap<String, String> sortedMap = new LinkedHashMap<>(listEntries.size());
    for (Entry<String, String> entry : listEntries) {
      sortedMap.put(entry.getKey(), entry.getValue());
    }

    System.out.println("----- After sorting by values -----");
    Set<Entry<String, String>> sortedEntries = sortedMap.entrySet();
    for (Entry<String, String> mapping : sortedEntries) {
      System.out.println(mapping.getKey() + " ==>> " + mapping.getValue());
    }
  }

}

Output:

----- Before sorting, random order -----
J2SE 1.2 ==>> Playground
JDK 1.1.4 ==>> Sparkler
J2SE 1.3 ==>> Kestrel
J2SE 1.4 ==>> Merlin
J2SE 5.0 ==>> Tiger
Java SE 7 ==>> Dolphin
Java SE 6 ==>> Mustang

----- After sorting by values -----
Java SE 7 ==>> Dolphin
J2SE 1.3 ==>> Kestrel
J2SE 1.4 ==>> Merlin
Java SE 6 ==>> Mustang
J2SE 1.2 ==>> Playground
JDK 1.1.4 ==>> Sparkler
J2SE 5.0 ==>> Tiger

Nguồn: http://www.java67.com/2015/01/how-to-sort-hashmap-in-java-based-on.html

Advertisement