Map使用方法


轉:https://www.cnblogs.com/lzq198754/p/5780165.html

 

Java map 詳解 - 用法、遍歷、排序、常用API等

概要:

java.util 中的集合類包含 Java 中某些最常用的類。最常用的集合類是 List 和 Map。

Map 提供了一個更通用的元素存儲方法。Map 集合類用於存儲元素對(稱作“鍵”和“值”),其中每個鍵映射到一個值。

本文主要介紹java map的初始化、用法、map的四種常用的遍歷方式、map的排序以及常用api。

1Map用法

類型介紹

Java 自帶了各種 Map 類。這些 Map 類可歸為三種類型:

1. 通用Map,用於在應用程序中管理映射,通常在 java.util 程序包中實現

HashMap、Hashtable、Properties、LinkedHashMap、IdentityHashMap、TreeMap、WeakHashMap、ConcurrentHashMap

2. 專用Map,通常我們不必親自創建此類Map,而是通過某些其他類對其進行訪問

java.util.jar.Attributes、javax.print.attribute.standard.PrinterStateReasons、java.security.Provider、java.awt.RenderingHints、javax.swing.UIDefaults

3. 一個用於幫助我們實現自己的Map類的抽象類

AbstractMap

類型區別

HashMap

最常用的Map,它根據鍵的HashCode 值存儲數據,根據鍵可以直接獲取它的值,具有很快的訪問速度。HashMap最多只允許一條記錄的鍵為Null(多條會覆蓋);允許多條記錄的值為 Null。非同步的。

TreeMap

能夠把它保存的記錄根據鍵(key)排序,默認是按升序排序,也可以指定排序的比較器,當用Iterator 遍歷TreeMap時,得到的記錄是排過序的。TreeMap不允許key的值為null。非同步的。 
Hashtable

與 HashMap類似,不同的是:key和value的值均不允許為null;它支持線程的同步,即任一時刻只有一個線程能寫Hashtable,因此也導致了Hashtale在寫入時會比較慢。 
LinkedHashMap

保存了記錄的插入順序,在用Iterator遍歷LinkedHashMap時,先得到的記錄肯定是先插入的.在遍歷的時候會比HashMap慢。key和value均允許為空,非同步的。 

Map 初始化

Java |  復制
1
Map<String, String> map =  new  HashMap<String, String>();

插入元素

Java |  復制
1
map.put( "key1" "value1" );

獲取元素

Java |  復制
1
map.get( "key1" )

移除元素

Java |  復制
1
map.remove( "key1" );

清空map

Java |  復制
1
map.clear();

2四種常用Map插入與讀取性能比較

測試環境

jdk1.7.0_80

測試結果

  插入10次平均(ms) 讀取10次平均(ms)
  1W 10W 100W 1W 10W 100W
HashMap 56 261 3030 2 21 220
LinkedHashMap 25 229 3069 2 20 216
TreeMap 29 295 4117 5 103 1446
Hashtable 24 234 3275 2 22 259

測試代碼

Java |  復制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
public  class  Test {
     static  int  hashMapW =  0 ;
     static  int  hashMapR =  0 ;
     static  int  linkMapW =  0 ;
     static  int  linkMapR =  0 ;
     static  int  treeMapW =  0 ;
     static  int  treeMapR =  0 ;
     static  int  hashTableW =  0 ;
     static  int  hashTableR =  0 ;
 
     public  static  void  main(String[] args) {
         for  ( int  i =  0 ; i <  10 ; i++) {
             Test test =  new  Test();
             test.test( 100  10000 );
             System.out.println();
         }
 
         System.out.println( "hashMapW = "  + hashMapW /  10 );
         System.out.println( "hashMapR = "  + hashMapR /  10 );
         System.out.println( "linkMapW = "  + linkMapW /  10 );
         System.out.println( "linkMapR = "  + linkMapR /  10 );
         System.out.println( "treeMapW = "  + treeMapW /  10 );
         System.out.println( "treeMapR = "  + treeMapR /  10 );
         System.out.println( "hashTableW = "  + hashTableW /  10 );
         System.out.println( "hashTableR = "  + hashTableR /  10 );
     }
 
     public  void  test( int  size) {
         int  index;
         Random random =  new  Random();
         String[] key =  new  String[size];
 
         // HashMap 插入
         Map<String, String> map =  new  HashMap<String, String>();
         long  start = System.currentTimeMillis();
         for  ( int  i =  0 ; i < size; i++) {
             key[i] = UUID.randomUUID().toString();
             map.put(key[i], UUID.randomUUID().toString());
         }
         long  end = System.currentTimeMillis();
         hashMapW += (end - start);
         System.out.println( "HashMap插入耗時 = "  + (end - start) +  " ms" );
 
         // HashMap 讀取
         start = System.currentTimeMillis();
         for  ( int  i =  0 ; i < size; i++) {
             index = random.nextInt(size);
             map.get(key[index]);
         }
         end = System.currentTimeMillis();
         hashMapR += (end - start);
         System.out.println( "HashMap讀取耗時 = "  + (end - start) +  " ms" );
 
         // LinkedHashMap 插入
         map =  new  LinkedHashMap<String, String>();
         start = System.currentTimeMillis();
         for  ( int  i =  0 ; i < size; i++) {
             key[i] = UUID.randomUUID().toString();
             map.put(key[i], UUID.randomUUID().toString());
         }
         end = System.currentTimeMillis();
         linkMapW += (end - start);
         System.out.println( "LinkedHashMap插入耗時 = "  + (end - start) +  " ms" );
 
         // LinkedHashMap 讀取
         start = System.currentTimeMillis();
         for  ( int  i =  0 ; i < size; i++) {
             index = random.nextInt(size);
             map.get(key[index]);
         }
         end = System.currentTimeMillis();
         linkMapR += (end - start);
         System.out.println( "LinkedHashMap讀取耗時 = "  + (end - start) +  " ms" );
 
         // TreeMap 插入
         key =  new  String[size];
         map =  new  TreeMap<String, String>();
         start = System.currentTimeMillis();
         for  ( int  i =  0 ; i < size; i++) {
             key[i] = UUID.randomUUID().toString();
             map.put(key[i], UUID.randomUUID().toString());
         }
         end = System.currentTimeMillis();
         treeMapW += (end - start);
         System.out.println( "TreeMap插入耗時 = "  + (end - start) +  " ms" );
 
         // TreeMap 讀取
         start = System.currentTimeMillis();
         for  ( int  i =  0 ; i < size; i++) {
             index = random.nextInt(size);
             map.get(key[index]);
         }
         end = System.currentTimeMillis();
         treeMapR += (end - start);
         System.out.println( "TreeMap讀取耗時 = "  + (end - start) +  " ms" );
 
         // Hashtable 插入
         key =  new  String[size];
         map =  new  Hashtable<String, String>();
         start = System.currentTimeMillis();
         for  ( int  i =  0 ; i < size; i++) {
             key[i] = UUID.randomUUID().toString();
             map.put(key[i], UUID.randomUUID().toString());
         }
         end = System.currentTimeMillis();
         hashTableW += (end - start);
         System.out.println( "Hashtable插入耗時 = "  + (end - start) +  " ms" );
 
         // Hashtable 讀取
         start = System.currentTimeMillis();
         for  ( int  i =  0 ; i < size; i++) {
             index = random.nextInt(size);
             map.get(key[index]);
         }
         end = System.currentTimeMillis();
         hashTableR += (end - start);
         System.out.println( "Hashtable讀取耗時 = "  + (end - start) +  " ms" );
     }
}

3Map 遍歷

初始化數據

Java |  復制
1
2
3
Map<String, String> map =  new  HashMap<String, String>();
map.put( "key1" "value1" );
map.put( "key2" "value2" );

增強for循環遍歷

使用keySet()遍歷

Java |  復制
1
2
3
for  (String key : map.keySet()) {
     System.out.println(key +  " :"  + map.get(key));
}

使用entrySet()遍歷

Java |  復制
1
2
3
for  (Map.Entry<String, String> entry : map.entrySet()) {
     System.out.println(entry.getKey() +  " :"  + entry.getValue());
}

迭代器遍歷

使用keySet()遍歷

Java |  復制
1
2
3
4
5
Iterator<String> iterator = map.keySet().iterator();
while  (iterator.hasNext()) {
     String key = iterator.next();
     System.out.println(key +  " :"  + map.get(key));
}

使用entrySet()遍歷

Java |  復制
1
2
3
4
5
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while  (iterator.hasNext()) {
     Map.Entry<String, String> entry = iterator.next();
     System.out.println(entry.getKey() +  " :"  + entry.getValue());
}

HashMap四種便利方式性能比較

比較方式

分別對四種遍歷方式進行10W次迭代,比較用時。

代碼

Java |  復制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package  net.xsoftlab.baike;
 
import  java.util.HashMap;
import  java.util.Iterator;
import  java.util.Map;
import  java.util.Map.Entry;
 
public  class  TestMap {
 
     public  static  void  main(String[] args) {
         // 初始化,10W次賦值
         Map<Integer, Integer> map =  new  HashMap<Integer, Integer>();
         for  ( int  i =  0 ; i <  100000 ; i++)
             map.put(i, i);
 
         /** 增強for循環,keySet迭代 */
         long  start = System.currentTimeMillis();
         for  (Integer key : map.keySet()) {
             map.get(key);
         }
         long  end = System.currentTimeMillis();
         System.out.println( "增強for循環,keySet迭代 -> "  + (end - start) +  " ms" );
 
         /** 增強for循環,entrySet迭代 */
         start = System.currentTimeMillis();
         for  (Entry<Integer, Integer> entry : map.entrySet()) {
             entry.getKey();
             entry.getValue();
         }
         end = System.currentTimeMillis();
         System.out.println( "增強for循環,entrySet迭代 -> "  + (end - start) +  " ms" );
 
         /** 迭代器,keySet迭代 */
         start = System.currentTimeMillis();
         Iterator<Integer> iterator = map.keySet().iterator();
         Integer key;
         while  (iterator.hasNext()) {
             key = iterator.next();
             map.get(key);
         }
         end = System.currentTimeMillis();
         System.out.println( "迭代器,keySet迭代 -> "  + (end - start) +  " ms" );
 
         /** 迭代器,entrySet迭代 */
         start = System.currentTimeMillis();
         Iterator<Map.Entry<Integer, Integer>> iterator1 = map.entrySet().iterator();
         Map.Entry<Integer, Integer> entry;
         while  (iterator1.hasNext()) {
             entry = iterator1.next();
             entry.getKey();
             entry.getValue();
         }
         end = System.currentTimeMillis();
 
         System.out.println( "迭代器,entrySet迭代 -> "  + (end - start) +  " ms" );
     }
}

運行三次,比較結果

第一次

Text |  復制
1
2
3
4
增強for循環,keySet迭代 -> 37 ms
增強for循環,entrySet迭代 -> 19 ms
迭代器,keySet迭代 -> 14 ms
迭代器,entrySet迭代 -> 9 ms

第二次

Text |  復制
1
2
3
4
增強for循環,keySet迭代 -> 29 ms
增強for循環,entrySet迭代 -> 22 ms
迭代器,keySet迭代 -> 19 ms
迭代器,entrySet迭代 -> 12 ms

第三次

Text |  復制
1
2
3
4
增強for循環,keySet迭代 -> 27 ms
增強for循環,entrySet迭代 -> 19 ms
迭代器,keySet迭代 -> 18 ms
迭代器,entrySet迭代 -> 10 ms

平均值

Text |  復制
1
2
3
4
增強for循環,keySet迭代 -> 31 ms
增強for循環,entrySet迭代 -> 20 ms
迭代器,keySet迭代 -> 17 ms
迭代器,entrySet迭代 -> 10.33 ms

總結

  1. 增強for循環使用方便,但性能較差,不適合處理超大量級的數據。

  2. 迭代器的遍歷速度要比增強for循環快很多,是增強for循環的2倍左右。

  3. 使用entrySet遍歷的速度要比keySet快很多,是keySet的1.5倍左右。

4Map 排序

HashMap、Hashtable、LinkedHashMap排序

注:

TreeMap也可以使用此方法進行排序,但是更推薦下面的方法。

Java |  復制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Map<String, String> map =  new  HashMap<String, String>();
map.put( "a" "c" );
map.put( "b" "b" );
map.put( "c" "a" );
 
// 通過ArrayList構造函數把map.entrySet()轉換成list
List<Map.Entry<String, String>> list =  new  ArrayList<Map.Entry<String, String>>(map.entrySet());
// 通過比較器實現比較排序
Collections.sort(list,  new  Comparator<Map.Entry<String, String>>() {
     public  int  compare(Map.Entry<String, String> mapping1, Map.Entry<String, String> mapping2) {
         return  mapping1.getKey().compareTo(mapping2.getKey());
     }
});
 
for  (Map.Entry<String, String> mapping : list) {
     System.out.println(mapping.getKey() +  " :"  + mapping.getValue());
}

TreeMap排序

TreeMap默認按key進行升序排序,如果想改變默認的順序,可以使用比較器:

Java |  復制
1
2
3
4
5
6
7
8
9
10
11
12
Map<String, String> map =  new  TreeMap<String, String>( new  Comparator<String>() {
     public  int  compare(String obj1, String obj2) {
         return  obj2.compareTo(obj1); // 降序排序
     }
});
map.put( "a" "c" );
map.put( "b" "b" );
map.put( "c" "a" );
 
for  (String key : map.keySet()) {
     System.out.println(key +  " :"  + map.get(key));
}

按value排序(通用)

Java |  復制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Map<String, String> map =  new  TreeMap<String, String>();
         map.put( "a" "c" );
         map.put( "b" "b" );
         map.put( "c" "a" );
 
         // 通過ArrayList構造函數把map.entrySet()轉換成list
         List<Map.Entry<String, String>> list =  new  ArrayList<Map.Entry<String, String>>(map.entrySet());
         // 通過比較器實現比較排序
         Collections.sort(list,  new  Comparator<Map.Entry<String, String>>() {
             public  int  compare(Map.Entry<String, String> mapping1, Map.Entry<String, String> mapping2) {
                 return  mapping1.getValue().compareTo(mapping2.getValue());
             }
         });
 
         for  (String key : map.keySet()) {
             System.out.println(key +  " :"  + map.get(key));
         }

5常用API

 

clear() 從 Map 中刪除所有映射
remove(Object key) 從 Map 中刪除鍵和關聯的值
put(Object key, Object value) 將指定值與指定鍵相關聯
putAll(Map t) 將指定 Map 中的所有映射復制到此 map
entrySet() 返回 Map 中所包含映射的 Set 視圖。Set 中的每個元素都是一個 Map.Entry 對象,可以使用 getKey() 和 getValue() 方法(還有一個 setValue() 方法)訪問后者的鍵元素和值元素
keySet() 返回 Map 中所包含鍵的 Set 視圖。刪除 Set 中的元素還將刪除 Map 中相應的映射(鍵和值)
values() 返回 map 中所包含值的 Collection 視圖。刪除 Collection 中的元素還將刪除 Map 中相應的映射(鍵和值)
get(Object key) 返回與指定鍵關聯的值
containsKey(Object key) 如果 Map 包含指定鍵的映射,則返回 true
containsValue(Object value) 如果此 Map 將一個或多個鍵映射到指定值,則返回 true
isEmpty() 如果 Map 不包含鍵-值映射,則返回 true
size() 返回 Map 中的鍵-值映射的數目


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM