hashmap 内部有一个数组,这个数组保存的是若干个内部类Entry, Entry有3个属性,key,value,next(Entry)
next(Entry)是指向下一个Entry的指针,目的是为了解决hash冲突而设计的链表
1.动态扩容
当调用put方法,函数会判断map的当前size/默认长度*负载因子,如果超过这个值,会动态扩容,原理是取出所有Entry(递归)到一个List,新建一个新的hash表,通过hash函数重新存储到这个表里
2.hash冲突
首先拿到当前key的hashcode取出Entry,对比key和Entry的key值,相等则取出Entry的value,不等则向下拿next(递归),直到相等,最后取出Entry的value
手写源码:
package test;
public interface MyMap {
public V put(K k,V v);
public V get(K k);
public int size();
public interface Entry {
public K getKey();
public V getValue();
}
}
package test;
import java.util.ArrayList;
import java.util.List;
public class MyHashMapimplements MyMap{private static int defaultLength=16;
private static double defaultLoader=0.75;
private Entry[] table=null;
private int size=0;
public MyHashMap(int a,double b){
defaultLength=a;
defaultLoader=b;
}public MyHashMap(){
this(defaultLength,defaultLoader);
}@Override
public V put(K k, V v) {
if(size>defaultLoader*defaultLength){
zpSize();
}if(table==null) {
table = new Entry[defaultLength];
}
int index = getIndex(k);
Entry kvEntry = table[index];
if(kvEntry == null){
table[index]=newEntry(k,v,null);
size++;
}else {
table[index]=newEntry(k,v,kvEntry);
}
return table[index].getValue();
}private void zpSize() {
Entry[] newTbale=new Entry[2*defaultLength];
againHash(newTbale);
}private void againHash(Entry[] newTbale) {
List> list=new ArrayList();
for(int i=0;
i0){
size=0;
defaultLength=defaultLength*2;
table=newTbale;
for(Entry entry:list){
if(entry.next!=null){
entry.next=null;
}
put(entry.getKey(),entry.getValue());
}
}}private void addNext(Entry kvEntry,List list) {
if(kvEntry.next!=null){
list.add(kvEntry.next);
addNext(kvEntry.next,list);
}
}private Entry newEntry(K k,V v,Entry next){
return new Entry<>(k,v,next);
}private int getIndex(K k){
int m=defaultLength;
int i = k.hashCode() % m;
return i>0?i:-i;
}@Override
public V get(K k) {
int index = getIndex(k);
Entry kvEntry = table[index];
if(k == kvEntry.getKey() || k.equals(kvEntry.getKey())){
return kvEntry.getValue();
}returngetNext(k, kvEntry);
}private V getNext(K k, Entry kvEntry) {
if(kvEntry.next==null){
return kvEntry.getValue();
}
if(k == kvEntry.next.getKey() || k.equals(kvEntry.next.getKey())){
return kvEntry.next.getValue();
}
returngetNext(k,kvEntry.next);
}@Override
public int size() {
return 0;
}class Entry implements MyMap.Entry{K k;
V v;
Entry next;
public Entry(K k,V v,Entry next){
this.k=k;
this.v=v;
this.next=next;
}@Override
public K getKey() {
return k;
}@Override
public V getValue() {
return v;
}
}
}
测试:
package test;
public class A {
public static void main(String[] args) {
//List list= Arrays.asList("3","1","2");
//list.sort(String::compareTo);
//list.sort(Comparator.reverseOrder());
//list.forEach((a)-> System.out.println(a));
MyHashMap map=new MyHashMap();
for(int i=1;
i<1000;
i++){
map.put(i,i);
}for(int i=1;
i<1000;
i++){
System.out.println(i+"----"+map.get(i));
}
}
}
【手写hashmap】
推荐阅读
- Springboot单元测试
- activiti|activiti课程导学(一)(慕课网)
- JAVA|intellij idea使用技巧汇总
- JAVA|Spring boot和Vue.js实现基于oauth2授权码模式的认证 (一)
- java|你知道哪些开源基金会()
- java|世界最著名的 16 个开源软件基金会,你认识哪几个呢()
- 资讯|世界上最大的开源基金会 Apache 是如何运作的()
- 冒泡排序(Bubble Sort)
- java|2022年深圳杯数学建模