Writer:BYSocket(泥沙磚瓦漿木匠)java
微博:BYSocketweb
豆瓣:BYSocket算法
Java 容器的文章此次應該是最後一篇了:Java 容器 系列。 今天泥瓦匠聊下 Maps。安全
Map,又稱映射表,是將鍵映射到值的對象。有四種實現Map接口而且常用的Map集合爲:HashMap,TreeMap,Hashtable 和 LinkedHashMap.併發
泥瓦匠記憶宮殿:框架
一、一個映射不包含重複的鍵。socket
二、每一個鍵最多只能映射到一個值。函數
HashMap是基於哈希表的Map接口的實現。其對鍵進行散列,散列函數只能做用於鍵。下面模擬下,公司員工和找員工的例子:oop
import java.util.HashMap; import java.util.Map; class Employee {} public class HaspMap01 { public static void main(String[] args) { Map<String, Employee> employees = new HashMap<String, Employee>(); employees.put("1206010035", new Employee()); System.out.println(employees); String number = "1206010035"; System.out.println(employees.get(number)); } }
?Run一下,你們能夠見到結果:put方法,能夠將鍵值映射添加進表。get方法則返回指定鍵所映射的值。從他們 hashCode 能夠看出是同一個對象。性能
HaspMap的鍵必須惟一,一樣其同一個鍵不能存放兩個值,若是對同一個鍵兩次調用put方法,第二個值會取代第一個值。一樣是容許使用 null 值和 null 鍵。下面泥瓦匠用一個簡單的例子解釋下:
package javaBasic.collection.map; import java.util.HashMap; import java.util.Map; public class HaspMap02 { @SuppressWarnings({ "unchecked", "rawtypes" }) public static void main(String[] args) { Map map = new HashMap<String, String>(); map.put(null, "null01"); map.put(null, "null02"); System.out.println(map); System.out.println(map.get(null)); } }
結果以下:
{null=null02} null02
因而可知,第一個值被第二個值所替換了。
下面有三點是HashMap重要之處:
一、HashMap的構造函數
HaspMap構造函數涉及兩個參數:初始容量和加載因子。初試容量是哈希表建立時的其中桶的含量。加載因子是哈希表在其容量自動增長以前能夠達到多滿的一種尺度。這兩個參數都是影響HashMap的性能。默認構造一個具備默認初始容量 (16) 和默認加載因子 (0.75)。默認加載因子 (.75) 在時間和空間成本上是一種折衷的考慮。
二、和上次總結的Set都差很少,這個HashMap線程是不安全不一樣步的。若是想防止意外發生,則設置成同步便可:
Map m = Collections.synchronizedMap(new HashMap(...));
三、不一樣步的話,意味着存在快速失敗致使的併發修改異常。
下面看一個複雜例子:
package javaBasic.collection.map; import java.util.HashMap; import java.util.Map.Entry; class A { public boolean equals(Object obj) { return true; } } class B { public int hashCode() { return 1; } } class C { public int hashCode() { return 2; } public boolean equals(Object obj) { return true; } } public class HashMap03 { public static void main(String[] args) { HashMap<A, Integer> hashMapA = new HashMap<A, Integer>(); hashMapA.put(new A(), 10); hashMapA.put(new A(), 5); System.out.println("HashMapA Elements:"); System.out.print("\t" + hashMapA + "\n"); // loop HashMapA for(Entry<A, Integer> entryA : hashMapA.entrySet()) { System.out.println(entryA.getKey().toString()+"-"+entryA.getValue()); } HashMap<B, Integer> hashMapB = new HashMap<B, Integer>(); hashMapB.put(new B(), 10); hashMapB.put(new B(), 5); System.out.println("HashMapB Elements:"); System.out.print("\t" + hashMapB + "\n"); // loop HashMapB for(Entry<B, Integer> entryB : hashMapB.entrySet()) { System.out.println(entryB.getKey().toString()+"-"+entryB.getValue()); } HashMap<C, Integer> hashMapC = new HashMap<C, Integer>(); hashMapC.put(new C(), 10); hashMapC.put(new C(), 5); System.out.println("HashMapC Elements:"); System.out.print("\t" + hashMapC + "\n"); // loop HashMap for(Entry<C, Integer> entryC : hashMapC.entrySet()) { System.out.println(entryC.getKey().toString()+"-"+entryC.getValue()); } } }
運行一下,能夠看到如下結果:
因而可知,其中和 Java 容器 & 泛型:3、HashSet,TreeSet 和 LinkedHashSet比較 中涉及的知識點一致:
集合判斷兩個元素相等不僅僅是equals方法,而且必須hashCode()方法返回值也要相等。
TreeMap使v用樹結構實現(紅黑樹),集合中的元素進行排序,可是添加、刪除和包含的算法複雜度爲O(log(n))。其實Map特性基本都是一致的,好比看下面的簡單例子:
public class TreeMap01 { @SuppressWarnings({ "rawtypes", "unchecked" }) public static void main(String[] args) { Map map = new TreeMap(); map.put("1", "1"); map.put("4", "4"); map.put("2", "2"); map.put("2", "3"); System.out.println(map); } }
結果以下:
{1=1, 2=3, 4=4}
從中咱們能夠看出
一、TreeMap實現了SortedMap,顧名思義,其表示爲有排序的集合。
二、一樣其同一個鍵不能存放兩個值,若是對同一個鍵兩次調用put方法,第二個值會取代第一個值。
HashMap與TreeMap
一、HashMap經過hashcode對其內容進行快速查找,而TreeMap中全部的元素都保持着某種固定的順序,若是你須要獲得一個有序的結果你就應該使用TreeMap(HashMap中元素的排列順序是不固定的)。HashMap中元素的排列順序是不固定的)。
二、 HashMap經過hashcode對其內容進行快速查找,而TreeMap中全部的元素都保持着某種固定的順序,若是你須要獲得一個有序的結果你就應該使用TreeMap(HashMap中元素的排列順序是不固定的)。集合框架」提供兩種常規的Map實現:HashMap和TreeMap (TreeMap實現SortedMap接口)。
三、在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。但若是您要按天然順序或自定義順序遍歷鍵,那麼TreeMap會更好。使用HashMap要求添加的鍵類明肯定義了hashCode()和 equals()的實現。 這個TreeMap沒有調優選項,由於該樹總處於平衡狀態。
Writer:BYSocket(泥沙磚瓦漿木匠)
微博:BYSocket
豆瓣:BYSocket