这里是修真院后端小课堂,每篇分享文从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时需不须要指定初始大小。
答:看状况。根据业务需求。