很晚了不多说了,直接贴代码,看完就会了解HashMap是如何实现数组+链表存储的,希望能给大家带来帮助,如果有疑问和纠正,请留言,第一时间回复
public class MyHashMap<K,V> {
public Node<K,V>[] table;
private static final int DEFAULT_INITAIL_CAPACITY = 1<<4;
//负载因子
private static final float DEFAULT_LOAD_FECTOR = 0.75f;
//非null的个数
private static int size;
private static int theshold;
static class Node<K,V>{
private int hash;
private K key;
private V value;
private Node<K,V> next;
public Node(int hash, K key, V value, Node<K, V> next) {
super();
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public int getHash() {
return hash;
}
public void setHash(int hash) {
this.hash = hash;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public Node<K, V> getNext() {
return next;
}
public void setNext(Node<K, V> next) {
this.next = next;
}
@Override
public String toString() {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(key+"("+hash+")");
stringBuffer.append("=");
stringBuffer.append(value);
stringBuffer.append(",");
if(null != next){
stringBuffer.append(next.toString());
}
return stringBuffer.toString();
}
}
/**
* 添加元素
* @param key
* @param value
*/
public void put(K key,V value){
//获取hash
int hash = Objects.hashCode(key);
//指定数组长度,初始化数组
int length = DEFAULT_INITAIL_CAPACITY;
if(table == null){
theshold = (int)(DEFAULT_INITAIL_CAPACITY * DEFAULT_LOAD_FECTOR);
table = new Node[length];
}
//根据hashCode取模算出数组下标
// int i = hash % length;
// &运算代替取模
int i = hash & (length -1);//0000-1111 0-15
//判断table[i]是否存在
if(null == table[i]){
table[i] = new Node<K, V>(hash,key,value,null);
}else{
Node<K,V> node = table[i];
//判断table[i].key是否等于传入的key
if((node.hash == hash) && (node.key == key ||((key !=null) && node.key.equals(key)))){
node.value = value;
}else{
for (int count = 0;; count++) {
if(null == node.next){
node.next = new Node<K, V>(hash,key,value,null);
break;
}
//判断next
if((node.next.hash ==hash) && (node.next.key == key || (key != null && node.next.key.equals(key)))){
node.next.value = value;
break;
}
node = node.next;
}
}
}
size++;
if(size >= theshold){
resize();
}
}
//扩容方法
private void resize(){
//大小翻倍
int newCapacity = table.length << 1;
theshold = (int)(newCapacity * DEFAULT_LOAD_FECTOR);
Node<K,V>[] newTable = new Node[newCapacity];
//转移数据
for (Node<K, V> oldNode : table) {
if(null == oldNode){
continue;
}
for (int count = 0;; count++) {
if(oldNode == null){
break;
}
Node<K,V> next = oldNode.next;
//新table的下标
int i = oldNode.hash & (newCapacity -1);
oldNode.next = newTable[i];
newTable[i] = oldNode;
oldNode = next;
}
}
//替换table
table = newTable;
}
/**
* 获取元素
* @param key
* @return
*/
public V get(K key){
//获取key的hash
int hash = Objects.hashCode(key);
//判断table
if(table == null || table.length <= 0){
return null;
}
//根据hashCode取模算出数组下标
// int i = hash % length;
// &运算代替取模
int i = hash & (table.length -1);//0000-1111 0-15
Node<K,V> node = table[i];
if(node == null){
return null;
}
//按断key是否相等
if((node.hash == hash) && ((node.key == key) || (key != null && node.key.equals(key)))){
return node.value;
}else{
for (int count = 0;; count++) {
if(node.next != null){
if((node.next.hash == hash) && ((node.next.key == key) || (key != null && node.next.key.equals(key)))){
return node.next.value;
}
node = node.next;
}
}
}
}
@Override
public String toString() {
StringBuffer stringBuffer = new StringBuffer("{");
for (Node<K, V> node : table) {
if( null == node){
continue;
}
stringBuffer.append(node.toString());
}
stringBuffer.append("}");
return stringBuffer.toString();
}
}