构造map接口:
package com.extHashMap;
import sun.awt.SunHints;
public interface ExtMap<K,V> {
V put(K k,V v);
V get(K k );
interface Entry<K,V>{
K getKey();
V getValue();
V setValue(V v);
}
}
构造HashMap:
package com.extHashMap;
/*
数组+单向链表的方式实现hashmap
*/
public class ExtHashMap<K, V> implements ExtMap<K, V> {
Node<K, V>[] tables = null;//懒加载,需要时才加载
//map长度
int size;
// 3.HashMap默认负载因子,负载因子越小,hash冲突机率越低, 根据每个链表的个数
float DEFAULT_LOAD_FACTOR = 0.75f;
// 4.table默认初始大小 16
static int DEFAULT_INITIAL_CAPACITY = 16; // 16
static int CAPACITY_NUM = 1;
@Override
public V put(K k, V v) {
//判断当前map是否为kong
if (null == tables) {
//按照默认长度创建map容器
tables = new Node[DEFAULT_INITIAL_CAPACITY];
}
//判断是否需要扩容
if (size >= (DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR * CAPACITY_NUM)) {
//扩容
resize();
}
//根据key值计算下标,获取当前node
int i = k.hashCode();
int index = i % (tables.length);
Node node = tables[index];
//判读是否存在hash冲突
if (node != null) {
//存在hash冲突
//遍历当前node链表
Node newNode = node;//引用传递
//假如只存在一个节点
while (newNode != null) {
//值或者引用相等
if (newNode.getKey().equals(k) || newNode.getKey() == k) {
//覆盖
return (V) newNode.setValue(v);
} else {
//添加,七上八下原则,新值在最前面
if (newNode.next == null) {
// 说明遍历到最后一个node ,添加node
node = new Node(k, v, node);
size++;
}
}
newNode = newNode.next;
}
} else {
//没有发生hash冲突、
node = new Node(k, v, null);
size++;
}
tables[index] = node;
return null;
}
private void resize() {
//扩容
Node[] nodes = new Node[(DEFAULT_INITIAL_CAPACITY << 1) * CAPACITY_NUM];
for (int i = 0; i < tables.length; i++) {
Node<K, V> table = tables[i];//获取链表
while (table != null){
K key = table.getKey();
int j = key.hashCode();
int index = j % (nodes.length);//新数组索引获取
//如果当前nodes[index]存在数据,则需要执行如下代码,如果不存在,正好把下一个置空
table.next = nodes[index];
//把旧节点的当前链表赋值给扩容后数组的指定索引位置
nodes[index] = table;
table = table.next;
}
}
tables = nodes;
// Node<K, V> table = tables[oldIndex];
// Node<K, V> tmpTable = table;
// while (tmpTable != null) {
//
// tmpTable = tmpTable.next;
// }
CAPACITY_NUM++;
nodes = null;/// 赋值为null---为了垃圾回收机制能够回收
}
// 测试方法.打印所有的链表元素
void print() {
for (int i = 0; i < tables.length; i++) {
Node<K, V> node = tables[i];
System.out.print("下标位置[" + i + "]");
while (node != null) {
System.out.print("[ key:" + node.getKey() + ",value:" + node.getValue() + "]");
node = node.next;
// if (node.next != null) {
// node = node.next;
// } else {
// // 结束循环
// node = null;
// }
}
System.out.println();
}
}
public Node getTableByIndex(K k) {
int i = k.hashCode();
int index = i % (tables.length);
return tables[index];
}
@Override
public V get(K k) {
Node<K, V> table = getTableByIndex(k);
while (table !=null){
if(table.getKey().equals(k) || table.getKey() == k){
return table.getValue();
}
table = table.next;
}
return null;
}
public static void main(String[] args) {
ExtHashMap<String, String> map = new ExtHashMap<>();
map.put("a", "b");
map.put("a", "g");
map.put("b", "h");
map.print();
System.out.println(map.get("b"));
}
}
class Node<K, V> implements ExtMap.Entry<K, V> {
// 存放Map 集合 key
private K key;
// 存放Map 集合 value
private V value;
// 下一个节点Node
Node<K, V> next;
public Node(K k, V v, Node<K, V> next) {
this.key = k;
this.value = v;
this.next = next;
}
@Override
public K getKey() {
return this.key;
}
@Override
public V getValue() {
return this.value;
}
@Override
public V setValue(V v) {
//设置新值,返回老的值
V oldValue = this.value;
this.value = v;
return oldValue;
}
}
单元测试:
package com.extHashMap;
public class Test003 {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
// 基于什么原则 后进选出 非公平锁与公平锁
ExtHashMap extHashMap = new ExtHashMap<String, String>();
extHashMap.put("1号", "1号");// 0
extHashMap.put("2号", "1号");// 1
extHashMap.put("3号", "1号");// 2
extHashMap.put("4号", "1号");// 3
extHashMap.put("6号", "1号");// 4
extHashMap.put("7号", "1号");
extHashMap.put("14号", "1号");
extHashMap.put("22号", "1号");
extHashMap.put("26号", "1号");
extHashMap.put("27号", "1号");
extHashMap.put("28号", "1号");
extHashMap.put("66号", "66");
System.out.println("扩容前数据....");
extHashMap.print();
System.out.println("扩容后数据....");
extHashMap.put("30号", "1号");
extHashMap.put("31号", "1号");
extHashMap.put("66号", "123466666");
extHashMap.print();
// 修改3号之后
System.out.println(extHashMap.get("66号"));
// System.out.println("扩容之前获取数据:" + extHashMap.get("1号"));
// extHashMap.print();
// System.out.println();
// // extHashMap.put(14 + "号", 14 + "号");
// // extHashMap.put(1 + "号", "4444号");
// System.out.println("扩容之后获取数据:" + extHashMap.get("1号"));
// extHashMap.print();
}
}