激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語(yǔ)言 - JAVA教程 - 舉例詳解Java編程中HashMap的初始化以及遍歷的方法

舉例詳解Java編程中HashMap的初始化以及遍歷的方法

2020-01-13 17:26goldensun JAVA教程

這篇文章主要介紹了Java編程中HashMap的初始化以及遍歷的方法,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下

一、HashMap的初始化
1、HashMap 初始化的文藝寫法
   HashMap 是一種常用的數(shù)據(jù)結(jié)構(gòu),一般用來(lái)做數(shù)據(jù)字典或者 Hash 查找的容器。普通青年一般會(huì)這么初始化:

 

?
1
2
3
4
HashMap<String, String> map =
  new HashMap<String, String>();
 map.put("Name", "June");
 map.put("QQ", "2572073701");

看完這段代碼,很多人都會(huì)覺(jué)得這么寫太啰嗦了,對(duì)此,文藝青年一般這么來(lái)了:
 

?
1
2
3
4
5
6
7
HashMap<String, String> map =
  new HashMap<String, String>() {
 {
 put("Name", "June");
 put("QQ", "2572073701");
 }
 };

   嗯,看起來(lái)優(yōu)雅了不少,一步到位,一氣呵成的趕腳。然后問(wèn)題來(lái)了,有童鞋會(huì)問(wèn):納尼?這里的雙括號(hào)到底什么意思,什么用法呢?哈哈,其實(shí)很簡(jiǎn)單,看看下面的代碼你就知道啥意思了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Test {
 /*private static HashMap< String, String> map = new HashMap< String, String>() {
  {
   put("Name", "June");
   put("QQ", "2572073701");
  }
 };*/
 public Test() {
  System.out.println("Constructor called:構(gòu)造器被調(diào)用");
 }
 static {
  System.out.println("Static block called:靜態(tài)塊被調(diào)用");
 }
 {
  System.out.println("Instance initializer called:實(shí)例初始化塊被調(diào)用");
 }
 public static void main(String[] args) {
  new Test();
  System.out.println("=======================");
  new Test();
 }
}

輸出:

?
1
2
3
4
5
6
Static block called:靜態(tài)塊被調(diào)用
Instance initializer called:實(shí)例初始化被調(diào)用
Constructor called:構(gòu)造器被調(diào)用
=======================
Instance initializer called:實(shí)例初始化被調(diào)用
Constructor called:構(gòu)造器被調(diào)用

也就是說(shuō)第一層括弧實(shí)際是定義了一個(gè)匿名內(nèi)部類 (Anonymous Inner Class),第二層括弧實(shí)際上是一個(gè)實(shí)例初始化塊 (instance initializer block),這個(gè)塊在內(nèi)部匿名類構(gòu)造時(shí)被執(zhí)行。這個(gè)塊之所以被叫做“實(shí)例初始化塊”是因?yàn)樗鼈儽欢x在了一個(gè)類的實(shí)例范圍內(nèi)。
上面代碼如果是寫在 Test 類中,編譯后你會(huì)看到會(huì)生成 Test$1.class 文件,反編譯該文件內(nèi)容:

?
1
D:\eclipse_indigo\workspace_home\CDHJobs\bin\pvuv\>jad -p Test$1.class
?
1
2
3
4
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: Test.java
?
1
2
3
4
5
6
7
8
9
10
11
12
package pvuv.zhaopin;
import java.util.HashMap;
// Referenced classes of package pvuv.zhaopin:
// Test
 class Test$1 extends HashMap // 創(chuàng)建了一個(gè) HashMap 的子類
 {
 Test$1()
 { // 第二個(gè) {} 中的代碼放到了構(gòu)造方法中去了
 put("Name", "June");
 put("QQ", "2572073701");
 }
 }
?
1
D:\eclipse_indigo\workspace_home\CDHJobs\bin\pvuv\>

2、推而廣之
  這種寫法,推而廣之,在初始化 ArrayList、Set 的時(shí)候都可以這么玩,比如你還可以這么玩:

?
1
2
3
4
5
6
7
8
List<String> names = new ArrayList<String>() {
{
for (int i = 0; i < 10; i++) {
 add("A" + i);
}
}
};
System.out.println(names.toString()); // [A0, A1, A2, A3, A4, A5, A6, A7, A8, A9]

3、Java7:增加對(duì) collections 的支持
在 Java 7 中你可以像 Ruby, Perl、Python 一樣創(chuàng)建 collections 了。
Note:這些集合是不可變的。

PS:由于原文[5]作者并沒(méi)有標(biāo)出 java 7 哪個(gè)小版本號(hào)引入的這些新特性,對(duì)于留言報(bào)錯(cuò)的同學(xué),請(qǐng)嘗試大于 1.7.0_09 或者 java8 試試?

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
List list = new ArrayList();
 list.add("item");
 String item = list.get(0);
 Set< String> set = new HashSet< String>();
 set.add("item");
 Map< String, Integer> map = new HashMap< String, Integer>();
 map.put("key", 1);
 int value = map.get("key");
 // 現(xiàn)在你還可以:
 List< String> list = ["item"];
 String item = list[0];
 
 Set< String> set = {"item"};
 
 Map< String, Integer> map = {"key" : 1};
 int value = map["key"];

4、文藝寫法的潛在問(wèn)題
    文章開(kāi)頭提到的文藝寫法的好處很明顯就是一目了然。這里來(lái)羅列下此種方法的壞處,如果這個(gè)對(duì)象要串行化,可能會(huì)導(dǎo)致串行化失敗。
  1.此種方式是匿名內(nèi)部類的聲明方式,所以引用中持有著外部類的引用。所以當(dāng)串行化這個(gè)集合時(shí)外部類也會(huì)被不知不覺(jué)的串行化,當(dāng)外部類沒(méi)有實(shí)現(xiàn)serialize接口時(shí),就會(huì)報(bào)錯(cuò)。

2.上例中,其實(shí)是聲明了一個(gè)繼承自HashMap的子類。然而有些串行化方法,例如要通過(guò)Gson串行化為json,或者要串行化為xml時(shí),類庫(kù)中提供的方式,是無(wú)法串行化Hashset或者HashMap的子類的,從而導(dǎo)致串行化失敗。解決辦法:重新初始化為一個(gè)HashMap對(duì)象:

?
1
new HashMap(map);

這樣就可以正常初始化了。

5、執(zhí)行效率問(wèn)題
   當(dāng)一種新的工具或者寫法出現(xiàn)時(shí),猿們都會(huì)來(lái)一句:性能怎么樣?(這和男生談?wù)撁眉埖谝痪湟话愣际牵?ldquo;長(zhǎng)得咋樣?三圍多少?”一個(gè)道理:))
關(guān)于這個(gè)兩種寫法我這邊筆記本上測(cè)試文藝寫法、普通寫法分別創(chuàng)建 10,000,000 個(gè) Map 的結(jié)果是 1217、1064,相差 13%。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Test {
 public static void main(String[] args) {
  long st = System.currentTimeMillis();
  /*
  for (int i = 0; i < 10000000; i++) {
   HashMap< String, String> map = new HashMap< String, String>() {
    {
     put("Name", "June");
     put("QQ", "2572073701");
    }
   };
  }
  System.out.println(System.currentTimeMillis() - st); // 1217
  */
  for (int i = 0; i < 10000000; i++) {
   HashMap< String, String> map = new HashMap< String, String>();
   map.put("Name", "June");
   map.put("QQ", "2572073701");
  }
  System.out.println(System.currentTimeMillis() - st); // 1064
 }
}

6、由實(shí)例初始化塊聯(lián)想到的一些變量初始化問(wèn)題
  從代碼上看,a 為什么可以不先聲明類型?你覺(jué)得 a、b、c 的值分別是多少?能說(shuō)明理由么?
TIPS:如果你對(duì)這塊機(jī)制不了解,建議試著反編譯一下字節(jié)碼文件。

6.1 測(cè)試源碼

?
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
public class Test {
 
 int e = 6;
 Test() {
  int c = 1;
  this.f = 5;
  int e = 66;
 }
 int f = 55;
 int c = 11;
 int b = 1;
 {
  a = 3;
  b = 22;
 }
 int a = 33;
 static {
  d = 4;
 }
 static int d = 44;
 
 int g = 7;
 int h = 8;
 public int test(){
  g = 77;
  int h = 88;
  System.out.println("h - 成員變量:" + this.h);
  System.out.println("h - 局部變量: " + h);
  return g;
 }
 public static void main(String[] args) {
  System.out.println("a: " + new Test().a);
  System.out.println("b: " + new Test().b);
  System.out.println("c: " + new Test().c);
  System.out.println("d: " + new Test().d);
  System.out.println("f: " + new Test().f);
  System.out.println("e: " + new Test().e);
  System.out.println("g: " + new Test().test());
 }
}

6.2 字節(jié)碼反編譯:

?
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
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: Test.java
import java.io.PrintStream;
public class Test
{
 Test()
 {
  this.e = 6;
  f = 55;
  this.c = 11;
  b = 1;
  a = 3;
  b = 22;
  a = 33;
  g = 7;
  h = 8;
  int c = 1;
  f = 5;
  int e = 66;
 }
 public int test()
 {
  g = 77;
  int h = 88;
  System.out.println((new StringBuilder("h - \u6210\u5458\u53D8\u91CF\uFF1A")).append(this.h).toString());
  System.out.println((new StringBuilder("h - \u5C40\u90E8\u53D8\u91CF: ")).append(h).toString());
  return g;
 }
 public static void main(String args[])
 {
  System.out.println((new StringBuilder("a: ")).append((new Test()).a).toString());
  System.out.println((new StringBuilder("b: ")).append((new Test()).b).toString());
  System.out.println((new StringBuilder("c: ")).append((new Test()).c).toString());
  new Test();
  System.out.println((new StringBuilder("d: ")).append(d).toString());
  System.out.println((new StringBuilder("f: ")).append((new Test()).f).toString());
  System.out.println((new StringBuilder("e: ")).append((new Test()).e).toString());
  System.out.println((new StringBuilder("g: ")).append((new Test()).test()).toString());
 }
 int e;
 int f;
 int c;
 int b;
 int a;
 static int d = 4;
 int g;
 int h;
 static
 {
  d = 44;
 }
}
6.3 output:
 a: 33
 b: 22
 c: 11
 d: 44
 f: 5
 e: 6
 h - 成員變量:8
 h - 局部變量: 88
 g: 77


二、HashMap遍歷方法示例
第一種:
  

?
1
2
3
4
5
6
Map map = new HashMap();
  Iterator iter = map.entrySet().iterator();
  while (iter.hasNext()) {
  Map.Entry entry = (Map.Entry) iter.next(); Object key = entry.getKey();
  Object val = entry.getValue();
  }

  效率高,以后一定要使用此種方式!
  第二種:
 

?
1
2
3
4
5
6
Map map = new HashMap();
 Iterator iter = map.keySet().iterator();
 while (iter.hasNext()) {
 Object key = iter.next();
 Object val = map.get(key);
 }

  效率低,以后盡量少使用!
  HashMap的遍歷有兩種常用的方法,那就是使用keyset及entryset來(lái)進(jìn)行遍歷,但兩者的遍歷速度是有差別的,下面請(qǐng)看實(shí)例:
 

?
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
public class HashMapTest {
 public static void main(String[] args) ...{
 HashMap hashmap = new HashMap();
 for (int i = 0; i < 1000; i ) ...{
 hashmap.put("" i, "thanks");
 }
 long bs = Calendar.getInstance().getTimeInMillis();
 Iterator iterator = hashmap.keySet().iterator();
 while (iterator.hasNext()) ...{
 System.out.print(hashmap.get(iterator.next()));
 }
 System.out.println();
 System.out.println(Calendar.getInstance().getTimeInMillis() - bs);
 listHashMap();
 }
 public static void listHashMap() ...{
 java.util.HashMap hashmap = new java.util.HashMap();
 for (int i = 0; i < 1000; i ) ...{
 hashmap.put("" i, "thanks");
 }
 long bs = Calendar.getInstance().getTimeInMillis();
 java.util.Iterator it = hashmap.entrySet().iterator();
 while (it.hasNext()) ...{
 java.util.Map.Entry entry = (java.util.Map.Entry) it.next();
 // entry.getKey() 返回與此項(xiàng)對(duì)應(yīng)的鍵
 // entry.getValue() 返回與此項(xiàng)對(duì)應(yīng)的值
 System.out.print(entry.getValue());
 }
 System.out.println();
 System.out.println(Calendar.getInstance().getTimeInMillis() - bs);
 }
 }

  對(duì)于keySet其實(shí)是遍歷了2次,一次是轉(zhuǎn)為iterator,一次就從hashmap中取出key所對(duì)于的value。而entryset只是遍歷了第一次,他把key和value都放到了entry中,所以就快了。
  注:Hashtable的遍歷方法和以上的差不多!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日韩精品一二区 | 99riav国产在线观看 | 免费a级黄色片 | www.mitao| 快播av在线 | 久久久青青草 | 久久久久女人精品毛片 | 毛片免费在线观看视频 | 7777奇米成人四色影视 | 96视频在线免费观看 | 91网站免费在线观看 | 免费a级黄色片 | 午夜伦情电午夜伦情电影 | 免费观看视频在线观看 | 桥本有菜免费av一区二区三区 | 国产黄色网页 | 国产美女视频黄a视频免费 日韩黄色在线播放 | 亚洲国产成人久久成人52 | 色婷婷av一区二区三区久久 | 欧美一级黄 | 天天操综 | 免费国产一级特黄久久 | chinese-xvideos| 久久久资源网 | 国产在线观看免费视频软件 | 在线成人www免费观看视频 | 久久久涩 | 国产免费让你躁在线视频 | 日本一区二区久久久 | 日韩大片在线永久观看视频网站免费 | 蜜桃网站免费 | 黄色va视频 | 久久综合婷婷 | 国产免费福利视频 | 羞羞的小视频 | av电影在线网站 | 黄色免费在线电影 | 一本精品999爽爽久久久 | 午夜视频导航 | 羞羞视频一区 | 国产精品美女久久久免费 |