前言
映射 (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());
}
}