程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 舉例詳解Java編程中HashMap的初始化和遍歷的辦法

舉例詳解Java編程中HashMap的初始化和遍歷的辦法

編輯:關於JAVA

舉例詳解Java編程中HashMap的初始化和遍歷的辦法。本站提示廣大學習愛好者:(舉例詳解Java編程中HashMap的初始化和遍歷的辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是舉例詳解Java編程中HashMap的初始化和遍歷的辦法正文


1、HashMap的初始化
1、HashMap 初始化的文藝寫法
   HashMap 是一種經常使用的數據構造,普通用來做數據字典或許 Hash 查找的容器。通俗青年普通會這麼初始化:

 

HashMap<String, String> map =
  new HashMap<String, String>();
 map.put("Name", "June"); 
 map.put("QQ", "2572073701");

看完這段代碼,許多人都邑認為這麼寫太煩瑣了,對此,文藝青年普通這麼來了:
 

HashMap<String, String> map =
  new HashMap<String, String>() {
 {
 put("Name", "June"); 
 put("QQ", "2572073701"); 
 }
 };

   嗯,看起來優雅了很多,一步到位,趁熱打鐵的趕腳。然後成績來了,有童鞋會問:納尼?這裡的雙括號究竟甚麼意思,甚麼用法呢?哈哈,其實很簡略,看看上面的代碼你就曉得啥意思了。

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:結構器被挪用");
 }
 static {
  System.out.println("Static block called:靜態塊被挪用");
 }
 {
  System.out.println("Instance initializer called:實例初始化塊被挪用");
 }
 public static void main(String[] args) {
  new Test();
  System.out.println("=======================");
  new Test();
 }
}

輸入:

 Static block called:靜態塊被挪用
 Instance initializer called:實例初始化被挪用
 Constructor called:結構器被挪用
 =======================
 Instance initializer called:實例初始化被挪用
 Constructor called:結構器被挪用

也就是說第一層括弧現實是界說了一個匿名外部類 (Anonymous Inner Class),第二層括弧現實上是一個實例初始化塊 (instance initializer block),這個塊在外部匿名類結構時被履行。這個塊之所以被叫做“實例初始化塊”是由於它們被界說在了一個類的實例規模內。
下面代碼假如是寫在 Test 類中,編譯後你會看到會生成 Test$1.class 文件,反編譯該文件內容:

D:\eclipse_indigo\workspace_home\CDHJobs\bin\pvuv\>jad -p Test$1.class
// 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

package pvuv.zhaopin;
import java.util.HashMap;
// Referenced classes of package pvuv.zhaopin:
// Test
 class Test$1 extends HashMap // 創立了一個 HashMap 的子類
 {
 Test$1()
 { // 第二個 {} 中的代碼放到了結構辦法中去了 
 put("Name", "June");
 put("QQ", "2572073701");
 }
 }

D:\eclipse_indigo\workspace_home\CDHJobs\bin\pvuv\>

2、推而廣之
  這類寫法,推而廣之,在初始化 ArrayList、Set 的時刻都可以這麼玩,好比你還可以這麼玩:

 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:增長對 collections 的支撐
在 Java 7 中你可以像 Ruby, Perl、Python 一樣創立 collections 了。
Note:這些聚集是弗成變的。

PS:因為原文[5]作者並沒有標出 java 7 哪一個小版本號引入的這些新特征,關於留言報錯的同窗,請測驗考試年夜於 1.7.0_09 或許 java8 嘗嘗?

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");
 // 如今你還可以: 
 List< String> list = ["item"];
 String item = list[0];
 
 Set< String> set = {"item"};
 
 Map< String, Integer> map = {"key" : 1};
 int value = map["key"];

4、文藝寫法的潛伏成績
    文章開首提到的文藝寫法的利益很顯著就是了如指掌。這裡來枚舉下此種辦法的害處,假如這個對象要串行化,能夠會招致串行化掉敗。
  1.此種方法是匿名外部類的聲明方法,所以援用中持有著內部類的援用。所以當串行化這個聚集時內部類也會被不知不覺的串行化,當內部類沒有完成serialize接口時,就會報錯。

2.上例中,實際上是聲清楚明了一個繼續自HashMap的子類。但是有些串行化辦法,例如要經由過程Gson串行化為json,或許要串行化為xml時,類庫中供給的方法,是沒法串行化Hashset或許HashMap的子類的,從而招致串行化掉敗。處理方法:從新初始化為一個HashMap對象:

new HashMap(map);

如許便可以正常初始化了。

5、履行效力成績
   當一種新的對象或許寫法湧現時,猿們都邑來一句:機能怎樣樣?(這和男生議論妹紙第一句普通都是:“長得咋樣?三圍若干?”一個事理:))
關於這個兩種寫法我這邊筆記本上測試文藝寫法、通俗寫法分離創立 10,000,000 個 Map 的成果是 1217、1064,相差 13%。

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、由實例初始化塊聯想到的一些變量初始化成績
  從代碼上看,a 為何可以不先聲明類型?你認為 a、b、c 的值分離是若干?能解釋來由麼?
TIPS:假如你對這塊機制不懂得,建議試著反編譯一下字節碼文件。

6.1 測試源碼

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 字節碼反編譯:

// 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


2、HashMap遍歷辦法示例
第一種:
  

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();
  }

  效力高,今後必定要應用此種方法!
  第二種:
 

 Map map = new HashMap();
  Iterator iter = map.keySet().iterator();
  while (iter.hasNext()) {
  Object key = iter.next();
  Object val = map.get(key);
  }

  效力低,今後盡可能少應用!
  HashMap的遍歷有兩種經常使用的辦法,那就是應用keyset及entryset來停止遍歷,但二者的遍歷速度是有差異的,上面請看實例:
 

 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() 前往與此項對應的鍵
  // entry.getValue() 前往與此項對應的值
  System.out.print(entry.getValue());
  }
  System.out.println();
  System.out.println(Calendar.getInstance().getTimeInMillis() - bs);
  }
  }

  關於keySet實際上是遍歷了2次,一次是轉為iterator,一次就從hashmap中掏出key所關於的value。而entryset只是遍歷了第一次,他把key和value都放到了entry中,所以就快了。
  注:Hashtable的遍歷辦法和以上的差不多!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved