在 Java 中按鍵對 HashMap 進行排序

Rashmi Patidar 2023年1月30日 2021年6月30日
  1. 使用 Java 中的 TreeMap 類對鍵集進行排序
  2. 使用 Java 8 函式對鍵集進行排序
  3. 理解 Java 中的 Map 初始化流函式
  4. 理解 Java 中的 Map 轉換流函式
在 Java 中按鍵對 HashMap 進行排序

Java 語言中的術語 HashMap 是派生自 Map 介面的集合。該集合或類存在於 java.util 包中,並將資料儲存在鍵值對中。請注意,Map 上不能有兩個鍵。如果插入重複鍵,則相應鍵的值將替換為較新的值。

使用 Java 中的 TreeMap 類對鍵集進行排序

下面的程式碼塊演示了按鍵對 HashMap 進行排序。

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

public class HashMapSortByKey {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("2", "Value5");
        map.put("3", "Value1");
        map.put("1", "Value2");
        map.put("4", "Value3");
        map.put("9", "Value4");
        map.put("hi11", "Value6");
        map.put("hi0", "Value7");
        System.out.print("Unordered List: ");
        for (String s : map.keySet()) {
            System.out.print(" " + s);
        }
        System.out.println();
        System.out.print("Ordered List: ");
        TreeMap<String, String> map1 = new TreeMap<>(map);
        for (String s : map1.keySet()) {
            System.out.print(" " + s);
        }
    }
}

在上面的程式碼塊中,使用帶有 new 關鍵字的 HashMap 的預設建構函式宣告瞭 map 物件。該語句建立 HashSet 類的例項並將值分配給 Map 介面引用。這些型別是相容的,因為 HashMap 類在內部實現了 Map 介面。

Map 使用一些鍵值進行初始化。插入是使用將鍵繫結到其指定值的 put 方法進行的。如果鍵已經存在於 Map 中並用指定的值覆蓋先前的值,則該方法返回 previous value。當鍵不在 Map 中時,該函式返回一個 null 值。如果鍵或值的屬性禁止插入值,它會丟擲 IllegalArgumentException

現在為了遍歷 Map,使用了 for-each 迴圈。map.keySet 函式返回 Map 中所有鍵的 Set 格式。keyset 函式在 for-each 迴圈中獲取一個集合,變數可以在該集合上進行迭代;因此,列印鍵。它將以無序格式列印值,並且沒有明確定義的使用者獲取輸出的方式。

為了對 Map 鍵進行排序,使用了 TreeSet 類。map 變數在例項化時作為 TreeSet 建構函式中的建構函式引數給出。該類實現了 Comparable 介面來對鍵進行排序。當結果對映 map1 被列印出來時,它會在輸出中列印排序後的鍵。

下面是上面程式碼塊的輸出。

輸出:

Unordered List:  1 hi11 2 3 4 9 hi0
Ordered List:  1 2 3 4 9 hi0 hi11

使用 Java 8 函式對鍵集進行排序

Java 8 提供了函數語言程式設計的特權,這有助於在鏈函式上工作。在下面的程式中,可以看到例項化和初始化發生在一條語句中。而在第一個示例程式碼中,填充 Map 是一項繁瑣的任務。下面給出了在單個語句中瞭解 Streams 和例項化對映的函式。

Streamsjava.util 包中的一個介面,它提供了一次性處理操作序列的靈活性。Streams 在發射器發射資料的管道中工作;它會根據使用者的需要進行過濾、處理、轉換等等。

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Stream;

import static java.util.AbstractMap.SimpleEntry;
import static java.util.stream.Collectors.toMap;

public class HashMapSortByKey {
    public static void main(String[] args) {
         Map<String, String> map = Stream.of(new SimpleEntry<>("key6", "value1"),
                new SimpleEntry<>("key12", "value2"),
                new SimpleEntry<>("key9", "value3"))
                .collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue));
        
        System.out.print("Unordered List: ");
        for (String s : map.keySet()) {
            System.out.print(" " + s);
        }
        Map<String, String> mapSortedByKey = map
                .entrySet()
                .stream()
                .sorted(Map.Entry.<String, String>comparingByKey().reversed())
                .collect(Collectors.toMap(Map.Entry::getKey,
                        Map.Entry::getValue,
                        (oldVal, newValue) -> oldValue,
                        LinkedHashMap::new));

        System.out.println();
        System.out.print("Ordered List: ");
        for (String s1 : mapSortedByKey.keySet()) {
            System.out.print(" " + s1);
        }
    }
}

理解 Java 中的 Map 初始化流函式

首先,Stream 呼叫 of() 函式,該函式按順序返回指定的流。該函式建立 SimpleEntry 類的物件以建立鍵值形式的對映。該類實現了 Entry 介面並具有返回 Map 集合檢視的 entrySet 方法。

一旦形成鍵值條目,就使用 collect 函式將值收集到對映中。它是一個終端函式,意味著在 collect 函式之後不能再呼叫更多的方法。該函式將流值打包或繫結到所需的資料結構中。

作為引數給出的輸入始終是 Collector 引用。toMapCollectors 類中的一個靜態函式,它返回一個將流元素繫結到 Map 中的 Collector。該函式採用鍵 Mapper 和鍵值 Function 作為其引數。現在,方法引用::運算子意味著呼叫指定類的函式。

在鍵對映器中,getKey 函式從填充的 EntrySet 流中提取鍵。類似地,在鍵值函式中,呼叫 getValue 函式以從 EntrySet 流中獲取值。

上面程式碼中的 Collector Function 變數是 Java 中的函式式介面,它們具有一個用於功能的抽象方法。抽象方法的定義在實現它們的類中定義。

理解 Java 中的 Map 轉換流函式

在剛剛形成的 map 例項上,呼叫 entrySet 函式。該函式返回 Map 條目的集合檢視,並出現在 Map 介面中。在這些條目上,呼叫 stream 方法來轉換順序流中的條目。在條目流上,sorted 函式被呼叫。

它需要一個 Comparator 來比較 Stream 元素。sorted 函式最終返回給定條目的排序流。comparingByKey 函式返回具有預設鍵順序的 Map.Entry 比較器。比較器返回一個鍵集;如果找到的鍵為空,它會從函式中丟擲 NullPointerException

當檢索到條目集時,將呼叫 reversed 函式以反轉集合中元素的順序。最後,通過 Map 流呼叫 collect 函式。該函式是一個終端運算子,因此,在 collect 函式之後不能呼叫任何操作。在函式中,呼叫 toMap 函式以將流轉換為 Map。

該函式有四個引數:keyMapper 是一個生成鍵的函式,valueMapper 是一個建立其值的對映函式,mergeFunction 是一個合併函式的 BinaryOperator,而 mapSupplier 是一個 Supplier 函式,它返回一個新的空 Map,其中插入了結果。最後,生成的控制檯輸出列印在上面。

輸出:

Unordered List:  key12 key6 key9
Ordered List:  key9 key6 key12
Rashmi Patidar avatar Rashmi Patidar avatar

Rashmi is a professional Software Developer with hands on over varied tech stack. She has been working on Java, Springboot, Microservices, Typescript, MySQL, Graphql and more. She loves to spread knowledge via her writings. She is keen taking up new things and adopt in her career.

LinkedIn

相關文章 - Java HashMap