JavaRush /Java Blog /Random-TW /有關地圖介面的最常見問題的解答

有關地圖介面的最常見問題的解答

在 Random-TW 群組發布
你好!今天我們將回答有關地圖的最常見問題,但首先,讓我們記住它是什麼。 有關地圖介面最常見問題的答案 - 1映射是一種包含一組鍵值對的資料結構。它的資料結構類似於字典,這就是它通常被稱為的原因。同時Map是一個接口,在標準jdk中包含了主要的實作:Hashmap、LinkedHashMap、Hashtable、TreeMap。最常用的實作是 Hashmap,因此我們將在範例中使用它。這是地圖的標準創建和填充的樣子:
Map<Integer, String> map = new HashMap<>();
map.put(1, "string 1");
map.put(2, "string 2");
map.put(3, "string 3");
這是透過鍵獲取值的方法:
String string1 = map.get(1);
String string2 = map.get(2);
String string3 = map.get(3);
如果以上所有內容都清楚了,那麼讓我們繼續回答常見問題吧!

0.如何迭代所有Map值

迭代值是您使用映射執行的最常見操作。所有鍵值對都儲存在內部 Map.Entry 介面中,要取得它們,您需要呼叫entrySet(). 它會傳回一組可以循環的對:
for(Map.Entry<Integer, String> entry: map.entrySet()) {
   // get key
   Integer key = entry.getKey();
   // get value
   String value = entry.getValue();
}

Или используя итератор:
Iterator<Map.Entry<Integer, String>> itr = map.entrySet().iterator();
while(itr.hasNext()) {
   Map.Entry<Integer, String> entry =  itr.next();
   // get key
   Integer key = entry.getKey();
   // get value
   String value = entry.getValue();
}

1. 如何將Map轉換為List

Map 介面有 3 個傳回元素列表的方法:
  • keySet() - 傳回一組鍵;
  • value() - 傳回值的集合;
  • EntrySet() - 傳回一組鍵值集。
如果您查看該類別的建構函數ArrayList,您會注意到有一個帶有 Collection 類型參數的建構子。由於 Set 是 Collection 的後代,因此上述所有方法的結果都可以傳遞給該類別的建構子ArrayList。因此,我們將創建新列表並用以下值填充它們Map
// key list
List<Integer> keyList = new ArrayList<>(map.keySet());
// value list
List<String> valueList = new ArrayList<>(map.values());
// key-value list
List<Map.Entry<Integer, String>> entryList = new ArrayList<>(map.entrySet());

2.如何對map key進行排序

對映射進行排序也是程式設計中相當常見的操作。您可以透過多種方式執行此操作:
  1. 將 Map.Entry 放入清單中並使用 Comparator對其進行排序。

    在比較器中,我們將僅比較成對的鍵:

    List> list = new ArrayList(map.entrySet());
    Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() {
       @Override
       public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
           return o1.getKey() - o2.getKey();
       }
    });
    

    如果您了解 lambda,則可以顯著縮短此條目:

    Collections.sort(list, Comparator.comparingInt(Map.Entry::getKey));
  2. 使用SortedMap,或更準確地說,它的實現TreeMap,它在其構造函數中採用 Comparator。此比較器將套用於映射鍵,因此鍵必須是實作該介面的類別Comparable

    SortedMap<Integer, String> sortedMap = new TreeMap<>(new Comparator<Integer>() {
       @Override
       public int compare(Integer o1, Integer o2) {
           return o1 - o2;
       }
    });

    當然,一切都可以使用 lambda 重寫:

    SortedMap<Integer, String> sortedMap = new TreeMap<>(Comparator.comparingInt(o -> o));

    與第一種方法不同,使用 SortedMap,我們始終以排序的形式儲存資料。

3. 如何對地圖值進行排序

在這裡,您應該使用類似於第一個鍵的方法 - 獲取值列表並在列表中對它們進行排序:
List <Map.Entry<Integer, String>> valuesList = new ArrayList(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() {
   @Override
   public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
       return o1.getValue().compareTo(o2.getValue());
   }
});
其 lambda 看起來像這樣:
Collections.sort(list, Comparator.comparing(Map.Entry::getValue));

4.HashMap、TreeMap、Hashtable有什麼差別

如前所述,Map 介面有 3 個主要實作。他們每個人都有自己的特質:
  1. 元素的順序。 HashMap並且Hashtable不保證項目將按照添加順序儲存。此外,它們不保證元素的順序不會隨著時間的推移而改變。反過來,TreeMap它保證按照元素添加的順序或按照給定的比較器儲存元素。

  2. 有效值。 HashMap允許你有一個鍵和一個空值,HashTable不行。如果比較器允許,TreeMap 只能使用 null 值。如果不使用比較器(透過按新增順序儲存對),則不允許使用 null。

  3. 同步。HashTable同步,其餘不同步。如果map不會被不同的執行緒訪問,建議使用HashMap而不是HashTable。

以及實現的一般比較:
哈希映射 哈希表 樹狀圖
元素順序 是的
null 作為值 是的 並不真地
線程安全 是的
搜尋元素的演算法複雜度 複雜度(1) 複雜度(1) O(logn)
底層資料結構 哈希表 哈希表 紅黑樹

5. 如何創建雙向地圖

有時有必要使用鍵和值都是唯一的資料結構,即映射將包含鍵-鍵對。此資料結構可讓您在地圖上建立“反向視圖/搜尋”。也就是說,我們可以透過值找到一個鍵,這種資料結構稱為雙向映射,不幸的是,JDK不支援這種結構。但幸運的是,它的實作可以在 Apache Common Collections 或 Guava 庫中找到。在那裡它分別被稱為 BidiMap 和 BiMap。這些實作對鍵和值的唯一性施加了限制。這創建了一對一的關係。

6. 如何建立空地圖

創建空地圖有兩種方法:
  1. 普通物件初始化:

    Map<Integer, String> emptyMap = new HashMap<>();
  2. 建立一個不可變的空映射:

    Map<Integer, String> emptyMap =  Collections.emptyMap();
當我們嘗試為這樣的地圖添加資料時,我們將收到: UnsupportedOperationException異常。在本文中,我們研究了您在使用地圖介面時可能遇到的最常見問題。
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION