位元詩人 [Java] 程式設計教學:使用 HashMap 物件

Java映射
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

前言

映射 (map) 是基於鍵值對 (key-value pair) 的非線性容器。HashMap 是 Java 的映射 (Map) 中常用的實作品。該實作品是基於雜湊表 (hash table)。此實作的基本操作是常數時間 (constant-time performance)。

除了 HashMap 外,還有同樣使用雜湊表的 Hashtable。後者和前者的差別在於後者有多執行緒安全性 (thread-safe)。如果沒有要寫多執行緒程式,使用 HashMap 即可。

建立 HashMap 物件

在預設情形下,Java 不會自動引入映射。要使用 HashMap 的話,需手動引入以下類別:

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

使用以下敘述來建立 HashMap 物件,並使用 Map 的公開方法:

Map<String, String> map = new HashMap<String, String>();

若需要使用 HashMap 特有的公開方法,則改用此敘述:

HashMap<String, String> map = new HashMap<String, String>();

存取 HashMap 物件的元素

使用 put() 函式為 Map 物件新增鍵值對。使用 get() 函式以鍵為索引取出 Map 物件的值。參考以下範例程式:

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

public class MainProgram
{
    public static void main (String[] args)
    {
        /* Create a HashMap object. */
        Map<String, String> map = new HashMap<String, String>();

        /* Add some pairs of data. */
        map.put("one", "eins");
        map.put("two", "zwei");
        map.put("three", "drei");

        /* Retrieve a pair of data. */
        assertCond("zwei" == map.get("two"));
    }

    /* Home-made assert. */
    public static void assertCond (boolean cond)
    {
        if (!cond)
            throw new IllegalArgumentException("Wrong condition");
    }
}

檢查特定元素是否存在

使用 containsKey() 函式來檢查特定鍵是否存在。使用 containsValue() 函式來檢查特定值是否存在。參考以下範例函式:

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

public class MainProgram
{
    public static void main (String[] args)
    {
        Map<String, String> map = new HashMap<String, String>();

        map.put("one", "eins");
        map.put("two", "zwei");
        map.put("three", "drei");

        /* Check whether some pair exists. */
        assertCond(map.containsKey("two"));
    }

    /* Home-made assert. */
    public static void assertCond (boolean cond)
    {
        if (!cond)
            throw new IllegalArgumentException("Wrong condition");
    }
}

從資料結構的觀點來看,映射是以鍵為索引、從映射取值。containsValue() 算是非標準界面。

移除 HashMap 物件的元素

使用 remove() 函式,以鍵為索引,從 Map 物件移除鍵值對。參考以下範例程式:

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

public class MainProgram
{
    public static void main (String[] args)
    {
        Map<String, String> map = new HashMap<String, String>();

        map.put("one", "eins");
        map.put("two", "zwei");
        map.put("three", "drei");

        assertCond(map.containsKey("two"));

        /* Remove a key-value pair. */
        map.remove("two");

        /* The value should not exist. */
        assertCond(!map.containsKey("two"));
    }

    /* Home-made assert. */
    public static void assertCond (boolean cond)
    {
        if (!cond)
            throw new IllegalArgumentException("Wrong condition");
    }
}

走訪 HashMap 物件

走訪鍵 (Key)

使用 keySet() 函式取得 Set (集合) 物件做為鍵的容器,再走訪該 Set 物件即可。參考以下範例程式:

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

public class MainProgram
{
    public static void main (String[] args)
    {
        Map<String, String> map = new HashMap<String, String>();

        map.put("one", "eins");
        map.put("two", "zwei");
        map.put("three", "drei");

        /* Create a set of keys. */
        Set<String> keys = map.keySet();

        /* Iterate over the set. */
        for (String k : keys)
            System.out.println(k + ": " + map.get(k));
    }
}

請小伙伴不要刻意背誦範例程式。我們對這個範例程式的知識來自於 keySet() 函式的說明文件

走訪值 (Value)

注意這裡用到另一個容器。使用 values() 回傳含有值的 Collection 容器。再對該容器走訪即可。參考以下範例程式:

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class MainProgram
{
    public static void main (String[] args)
    {
        Map<String, String> map = new HashMap<String, String>();

        map.put("one", "eins");
        map.put("two", "zwei");
        map.put("three", "drei");

        /* Create a collection of values. */
        Collection<String> values = map.values();

        /* Iterate over the collection. */
        for (String v : values)
            System.out.println(v);
    }
}

從資料結構的觀點來看,應該是先從映射取得鍵,再以鍵為索引,逐一取得相對應的值。但現代高階語言為了方便,通常會提供直接走訪值的函式,Java 也不例外。

走訪鍵值對 (Entry)

鍵值對 (Map.Entry) 是包含鍵和值的小型容器。使用 entrySet() 函式取出鍵值對後,再視需求分別取鍵或取值,可以省下雜湊運算的時間。參考以下範例程式:

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

public class MainProgram
{
    public static void main (String[] args)
    {
        Map<String, String> map = new HashMap<String, String>();

        map.put("one", "eins");
        map.put("two", "zwei");
        map.put("three", "drei");

        /* Create a set of map entries. */
        Set<Map.Entry<String, String>> entries = map.entrySet();

        /* Iterate over the set. */
        for (var e : entries)
            System.out.println(e.getKey() + ": " + e.getValue());
    }
}
關於作者

身為資訊領域碩士,位元詩人 (ByteBard) 認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

位元詩人喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,位元詩人將所學寫成文章,放在這個網站上和大家分享。