你好!今天我們要講的是另一個資料結構—Map。它的官方俄語名稱是“關聯數組”,但並不經常使用。更常見的選項是「字典」、「地圖」或(最常見的)俚語「地圖」:) 在 Map 內部,資料以「鍵」-「值」格式存儲,即成對儲存。鍵和值都可以是任何物件-數字、字串或其他類別的物件。
Map 與其他資料結構有何不同
之前,我們研究了元素單獨儲存的資料結構。在陣列或ArrayList / LinkedList中,我們儲存一定數量的元素。但是如果我們的任務稍微改變呢?例如,假設我們面臨創建 100 人清單的任務,其中將儲存該人的全名和護照號碼。原則上來說,這並不是那麼困難。例如,您可以將兩者放入一行並建立行列表,如下所示: “Anna Ivanovna Reshetnikova,4211 717171.” 但這個解決方案有兩個缺點。首先,我們可能需要護照搜尋功能。而採用這種儲存資訊的格式,就會出現問題。其次,沒有什麼可以阻止我們創建兩個具有相同護照號碼的不同人。這是我們解決方案最嚴重的缺點。這種情況應該完全排除;沒有兩個人的護照號碼相同。在這裡,Map 及其聲明的功能可以為我們提供幫助(以「鍵」-「值」格式將資料儲存在一對中)。讓我們來看看最常見的Map實作——Java HashMap類別。在 Java 中建立 HashMap 並使用該類
這個實作的創建非常簡單:public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
}
在這裡,我們創建了一個字典,其中元素將以“數字字串”格式儲存。數字將是鍵,字串將是值。我們也指出了我們將擁有什麼類型的按鍵 ( Integer
) 以及我們將擁有什麼類型的值 ( String
)。為什麼會這樣呢?首先,HashMap 中的鍵始終是唯一的。這對我們來說非常有用,因為我們可以使用護照號碼作為鑰匙並避免重複。帶有全名的行將充當一個值(不同人的全名很容易重複,這對我們來說沒有問題)。
將新對添加到 HashMap
這個任務看起來像這樣:public class Main {
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
passportsAndNames.put(8082771, "Donald John Trump");
System.out.println(passportsAndNames);
}
}
該方法就是用於此目的put()
。此外,HashMap 有一個重寫的方法toString()
,因此可以將其列印到控制台。輸出將如下所示: {212133=Lidiya Arkadyevna Bublikova,8082771=Donald John Trump,162348=Ivan Mikhailovich Serebryakov}
HashMap鍵的特點
現在讓我們檢查一下這些鍵是否真的是唯一的?讓我們嘗試新增一個帶有映射中 已有鍵的新元素:public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
passportsAndNames.put(8082771, "Donald John Trump");
passportsAndNames.put(162348, "Viktor Mikhailovich Stychkin");//repeat key
System.out.println(passportsAndNames);
}
輸出: {212133=Lidiya Arkadyevna Bublikova,8082771=Donald John Trump,162348=Viktor Mikhailovich Stychkin} 如您所見,前一個帶有鍵 162348 的元素已被覆蓋。「鑰匙」被稱為鑰匙是有原因的。HashMap 中的值是透過鍵來存取的(但反之則不然——鍵不能透過值來獲取,因為值可以重複)。這在獲取元素以及從 HashMap 中刪除元素的範例中可以清楚地看到:
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
passportsAndNames.put(8082771, "Donald John Trump");
String lidiaName = passportsAndNames.get(212133);
System.out.println(lidiaName);
passportsAndNames.remove(162348);
System.out.println(passportsAndNames);
}
為了取得一個值或從字典中刪除一個值對,我們必須將與該值對應的唯一鍵準確地傳遞給get()
方法。HashMap 中沒有像數組或列表中那樣的數字索引- 值是透過鍵存取的。控制台輸出: Lidiya Arkadyevna Bublikova {212133=Lidiya Arkadyevna Bublikova,8082771=唐納德·約翰·特朗普}remove()
檢查鍵和值是否存在
在ArrayList和LinkedList類別中,我們可以檢查清單是否包含特定元素。 HashMap還允許您執行此操作,並且對於該對的兩個部分:它具有方法containsKey()
(檢查鍵是否存在)和containsValue()
(檢查值是否存在)。
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
passportsAndNames.put(8082771, "Donald John Trump");
System.out.println(passportsAndNames.containsKey(11111));
System.out.println(passportsAndNames.containsValue("Donald John Trump"));
}
輸出: 假真
取得所有鍵和值的列表
HashMap的另一個方便的功能是你可以分別取得所有按鍵和所有值的清單。為此,使用方法keySet()
和values()
:
public class Main {
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
passportsAndNames.put(8082771, "Donald John Trump");
Set<Integer> keys = passportsAndNames.keySet();
System.out.println("Keys: " + keys);
ArrayList<String> values = new ArrayList<>(passportsAndNames.values());
System.out.println("Values: " + values);
}
}
鍵被提取到集合中Set
。它的特點是它不能包含重複元素。現在要記住的主要事情是,可以將所有按鍵的清單從 HashMap 中取出到一個單獨的集合中。在範例中,我們將值儲存為 normal ArrayList
。控制台輸出: 鍵:[212133, 8082771, 162348] 值:[Lidiya Arkadyevna Bublikova, Donald John Trump, Ivan Mikhailovich Serebryakov] 方法size()
執行的clear()
操作與我們之前的結構完全相同:第一個返回數字元素在當前的字典中,第二個刪除所有元素。
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
passportsAndNames.put(8082771, "Donald John Trump");
System.out.println(passportsAndNames.size());
passportsAndNames.clear();
System.out.println(passportsAndNames);
}
輸出: 3 {} 要檢查我們的 HashMap 是否至少有一個元素,我們可以使用以下方法isEmpty()
:
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
passportsAndNames.put(8082771, "Donald John Trump");
if (!passportsAndNames.isEmpty()) {
System.out.println(passportsAndNames);
}
}
輸出: {212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump, 162348=Ivan Mikhailovich Serebryakov} 現在我們只有在初步驗證後才會輸出到控制台:)
將兩張地圖合併為一張
另一個有趣的點是兩張地圖可以合併為一張。有一個方法可以做到這一點putAll()
。我們在第一個HashMap上呼叫它,將第二個 HashMap 作為參數傳遞,第二個 HashMap 中的元素將會加入第一個:
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
HashMap<Integer, String> passportsAndNames2 = new HashMap<>();
passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
passportsAndNames.put(8082771, "Donald John Trump");
passportsAndNames2.put(917352, "Alexey Andreevich Ermakov");
passportsAndNames2.put(925648, "Maxim Olegovich Arkharov");
passportsAndNames.putAll(passportsAndNames2);
System.out.println(passportsAndNames);
}
輸出: {917352=Alexey Andreevich Ermakov, 212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump , 925648=Maxim Olegovich Arkharov, 162348=Ivan Mikhailovich Serebridim Olegovich Name的所有 元素。現在讓我們來看一個更複雜的例子。即,在循環中迭代 HashMap。
for (Map.Entry entry: passportsAndNames.entrySet()) {
System.out.println(entry);
}
介面Map.Entry
只是指字典中的鍵值對。這個方法entrySet()
傳回 HashMap 中所有對的列表(因為我們的映射僅包含這樣的 Entry 對,所以我們迭代對,而不是單獨的鍵或值)。結論: 212133=Lidiya Arkadyevna Bublikova 8082771=Donald John Trump 162348=Ivan Mikhailovich Serebryakov 保存這篇文章以供將來使用:https://habr.com/ru/post/128017/ 現在閱讀它還為時過早,但在將來,當您開始使用 HashMap 時,它將幫助您從內部理解這種資料結構的工作原理。另外,不要忘記查看有關 HashMap 的Oracle官方文件。
GO TO FULL VERSION