這裏是修真院後端小課堂,每篇分享文從html
【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴展思考】【更多討論】【參考文獻】node
八個方面深度解析後端知識/技能,本篇分享的是:程序員
【HashMap淺析?】後端
你們好,我是IT修真院武漢分院學員,一枚正直善良的JAVA程序員。數組
今天給你們分享一下,修真院官網JAVA任務10中的深度思考,HashMap淺析?數據結構
1、背景介紹併發
HashMap的存儲結構是由數組和鏈表共同組成的。因此HashMap有兩張存儲方式。能夠中和數組和鏈表的優缺點。this
數組的存儲方式在內存的地址是連續的,大小固定,一代分配後不能被其餘引用佔用。特定是查詢快,時間複雜度是O(1),插入和刪除的操做比較慢,時間複雜度是O(n),鏈表的存儲方式是非連續的,大小不固定,特定與數組相反,插入和刪除快,查詢速度慢。編碼
HashMap的基本原理線程
首先判斷Key是否爲null,若是是,直接查找Entry[0],若是不是,先計算Key的HashCode,而後經二次Hash。獲得Hash值,這個Hash的特徵值是一個int值。
根據Hash值,對Entry[]的長度求餘,獲得Entry數組的index。
找到對應的數組,就找到對應的鏈表,而後按鏈表的操做對Value進行插入、刪除和查詢操做。
二.知識剖析
hash的功能是要保證元素儘可能的在桶(buckets)中均勻分配。
Entry
table 在第一次使用的時候被初始化,以後若是須要還能夠調整大小,長度一般是是2的乘方。(某些狀況下也能夠爲0。)
threshold根據當前初始化大小和家長因子計算的邊界大小。當桶中的鍵值對超過這個大小就進行擴容。
Node節點。
initial capacity是hash table中被建立的buckets的數量。load factor是用來衡量在capacity自動增加前,hash table能夠被使用多少。當hash table中的entries使用數超過了load factor,capacity就會被從新hash,這樣hash table的大小將成爲以前兩倍左右。
capacity(buckets的數量)和size(鍵值對的數量)的加和,會使迭代集合視圖。因此不要把初始化大小設置過大,load factor也不要設置太小。0.75在時間和空間上是個比較好的數值。
HashMap是不一樣步的,若是多個線程同時併發訪問一個hash map, 當修改結構(不包括修改map的value)時必須在外部同步。
下面是一個單向鏈表。能夠經過下面的鏈接找到其於的雙向鏈表,雙端鏈表代碼。
package com.example.t;
/**
* Created by Administrator on 2018/8/9.
*/
public class OrderLinkedList {
private Node head;
private class Node{
private int data;
private Node next;
public Node(int data){
data = data;
}
}
public OrderLinkedList(){
head = null;
}
//插入節點,按照從小到大的順序排列。
public void insert(int value){
Node node = new Node(value);
Node pre = null;
Node current = head;
while (current != null && value > current.data){
pre = current;
current = current.next;
}
if (pre == null){
head = node;
head.next = current;
}else {
pre.next = node;
node.next = current;
}
}
//刪除頭節點。
public void deleteHead(){
head = head.next;
}
public void display(){
Node current = head;
while (current != null){
System.out.print(current.data + " ");
current = current.next;
}
System.out.println();
}
}
3、常見問題
1.鏈表是什麼?
四.解決方案
1.答:鏈表(Linked list)是一種常見的基礎數據結構,是一種線性表,可是並不會按線性的順序存儲數據,而是在每個節點裏存到下一個節點的指針(Pointer)。
五。編碼實戰
6、參考文獻
https://www.cnblogs.com/wuhua...
https://www.cnblogs.com/o-and...
https://www.cnblogs.com/coder...
https://www.cnblogs.com/ysoce...
8.更多討論
8.更多討論
答:每一個節點中只保存指向下一個節點的引用。
public class OrderLinkedList {
private Node head;
private class Node{
private int data;
private Node next;
public Node(int data){
data = data;
}
}
public OrderLinkedList(){
head = null;
}
//some code
}
答:每一個鏈節中保存了這個鏈節先後鏈節的引用。能夠經過一個鏈節向前或向後查詢。
public class TwoWayLinkedList {
private Node head;//表示鏈表頭
private Node tail;//表示鏈表尾
private int size;//表示鏈表的節點個數
private class Node{
private Object data;
private Node next;
private Node prev;
public Node(Object data){
this.data = data;
}
}
public TwoWayLinkedList(){
size = 0;
head = null;
tail = null;
}
//some code
}
23
3.雙端鏈表和雙向鏈表的差異?
答:雙端鏈表的查詢方向是頭部-->尾部,和尾部-->頭部。雙向鏈表是每一個鏈節均可以向兩個方向查詢。
4.使用HashMap時需不須要指定初始大小。
答:看狀況。根據業務需求。