如上图,HashMap是一个链表结构,获取位置下标的时候是通过hash算法来计算下标位置,同时,在存放的值超过整个容量的0.75之后会自动扩容,而且扩容之后需要重新获取entry的next指针,并且在put的时候要进行判断,这个操作是新增还是修改.
首先,定义一个MyMap接口,包含三个方法以及键值对对象:
public interface MyMap<K, V> {
// 向集合中插入值
public V put( K k, V v );
// 根据key获取集合中的值
public V get( K k );
// 获得集合中元素个数
public int size();
// 用于获取集合中,键值对的对象
interface Entry<K, V> {
K getKey();
V getValue();
V setValue( V value );
Entry<K, V> getNext();
Entry<K, V> setNext( Entry<K, V> next );
}
}
然后,定义MyHashMap继承上方接口,按照HashMap的实现逻辑去一步步实现:
public class MyHashMap<K, V> implements MyMap<K, V> {
/**
* 根据hash算法,理论上只需要查找一次就能查找到值
* Entry 类型数组,默认长度16
*/
private Entry<K, V> table[] = null;
// Hashmap的元素个数
private int size;
// hashmap集合中的数组的默认长度
private static int defaultLength = 16;
// 定义hashmap的加载银子0.75
private static double defaltLoad = 0.75f;
@Override
public V put( K k, V v ) {
if ( table == null ) {
table = new Entry[this.defaultLength];
}
if ( size >= this.defaultLength * this.defaltLoad ) {
// 扩容
resize();
}
// 1.分院,确定key/value存放吃的数组的下标位置
int index = getIndex( k, this.defaultLength );
// 判断是不是修改
MyMap.Entry<K, V> entry = table[ index ];
while( entry != null ) {
if ( entry.getKey()
.equals( k ) ) {
return entry.setValue( v );
} else {
entry = entry.getNext();
}
}
// 2.创建元素,并且存放在table的index下标上
table[ index ] = new Entry<>( k, v, table[ index ] );
this.size++;
return v;
}
private void resize() {
// 重新散列
if ( size >= this.defaultLength * this.defaltLoad ) {
System.out.println( "扩容开始..." );
Entry<K, V> newTable[] = new Entry[this.defaultLength << 1];
MyMap.Entry<K, V> entry = null;
for( int i = 0; i < table.length; i++ ) {
entry = table[ i ];
while( entry != null ) {
int index = getIndex( entry.getKey(), newTable.length );
MyMap.Entry<K, V> oldEntry = entry.getNext();
entry.setNext( newTable[ index ] );
newTable[ index ] = (Entry<K, V>) entry;
// 继续下一个节点
entry = oldEntry;
}
}
table = newTable;
this.defaultLength = newTable.length;
newTable = null;
}
}
public int getIndex( K k, int length ) {
if ( k == null ) {
return 0;
}
int hash = k.hashCode();
// 与算法 & 取模
return hash & ( length - 1 );
}
@Override
public V get( K k ) {
if ( table != null ) {
int index = getIndex( k, this.defaultLength );
MyMap.Entry<K, V> entry = table[ index ];
while( entry != null ) {
if ( entry.getKey()
.equals( k ) ) {
return entry.getValue();
} else {
entry = entry.getNext();
}
}
}
return null;
}
@Override
public int size() {
return this.size;
}
// Entry
static class Entry<K, V> implements MyMap.Entry<K, V> {
K key;
V value;
MyMap.Entry<K, V> next;
public Entry( K key, V value, MyMap.Entry<K, V> next ) {
super();
this.key = key;
this.value = value;
this.next = next;
}
@Override
public K getKey() {
return this.key;
}
@Override
public V getValue() {
// TODO Auto-generated method stub
return this.value;
}
@Override
public V setValue( V value ) {
V oldValue = this.value;
this.value = value;
return oldValue;
}
@Override
public MyMap.Entry<K, V> getNext() {
return this.next;
}
@Override
public MyMap.Entry<K, V> setNext( MyMap.Entry<K, V> next ) {
MyMap.Entry<K, V> oldNext = this.next;
this.next = next;
return oldNext;
}
}
}
最后,测试:
public class Test {
public static void main( String[] args ) {
MyHashMap<String, String> map = new MyHashMap<>();
map.put( "1号", "打的" );
map.put( "2号", "大的" );
map.put( "3号", "的的" );
map.put( "4号", "改动的" );
map.put( "5号", "改个的" );
map.put( "6号", "更大的" );
map.put( "7号", "发" );
map.put( "8号", "发呆" );
map.put( "9号", "更大" );
map.put( "10号", "更大啊" );
map.put( "11号", "啊" );
map.put( "12号", "个" );
map.put( "13号", "人" );
map.put( "14号", "让的" );
map.put( "15号", "个的" );
map.put( "16号", "发给谁" );
map.put( "17号", "但是" );
map.put( "18号", "凡事" );
map.put( "19号", "给谁" );
map.put( "20号", "凡事" );
map.put( "21号", "胜多负少" );
map.put( "22号", "发顺丰" );
map.put( "23号", "凡事的" );
map.put( "24号", "凡事发的" );
map.put( "25号", "发呆" );
map.put( "26号", "佛挡杀佛 " );
map.put( "27号", "凡事的" );
map.put( "28号", "凡事发多少" );
map.put( "29号", "发生的的" );
map.put( "30号", "凡事的" );
map.put( "31号", "fsfds" );
map.put( "32号", "萨芬" );
System.out.println( map.get( "17号" ) );
}
}
测试结果:扩容开始...
扩容开始...
但是
下面我们看看与1.8的差别:
以及数据结构的差别:
至此,我们可以看出两者之间的差别.