public class MyHashMap<K,V>{
/**
* 做不到手撕红黑树
* 基于1.7 简易实现
* 数组下标 使用hashcode % n来计算
* capcity 表示默认容量
*/
class Node<K,V>{
private K key;
private V value;
private Node<K,V> next; //表示链表的下一个节点
public Node(K key,V value){
this.key = key;
this.value = value;
}
public Node(K key,V value,Node<K,V> next){
this.key = key;
this.value = value;
this.next = next;
}
}
final int default_cap = 16;
final float yinzi = 0.75f;
private int size;
Node<K,V>[] buckets; //链表桶
public MyHashMap(){
buckets = new Node[default_cap];
this.size = 0;
}
public MyHashMap(int cap){
buckets = new Node[cap];
this.size = 0;
}
//getIndex 获取桶下标索引
public int getIndex(K key,int length){
int hashCode = key.hashCode();
int index = Math.abs(hashCode % length);
return index;
}
public void put(K key,V value){
//考虑扩容 3*0.75
if(size+1 >= buckets.length * yinzi){
System.out.println(size+",cur:"+buckets.length * yinzi);
resize();
}
//调用该方法真正去加入数据
putValue(key, value,buckets);
}
public void putValue(K key, V value, MyHashMap<K, V>.Node<K, V>[] table) {
int index = getIndex(key, table.length);
Node node = table[index];
if(node == null){
table[index] = new Node<K,V>(key, value);
size++;
return;
}else{
while(node != null){
//看一下有没有重复的 重复就覆盖掉
if(node.key.hashCode() == key.hashCode() && (node.key == key || node.key.equals(key))){
//表示遇到重复的key了 覆盖
node.value = value;
return;
}else{
node = node.next;
}
}
//如果遍历完链表后没有重复的 那就在头部插入
Node newhead = new Node<>(key, value, table[index]); //头插法 table[index]表示链表头
table[index] = newhead;
size++;
}
}
private void resize() {
Node<K,V>[] newBuckets = new Node[2*buckets.length];
size = 0; //resize的时候 这个需要重置为0
for(int i=0;i<buckets.length;i++){
if(buckets[i] == null) continue;
Node<K,V> node = buckets[i];
while(node != null){
putValue(node.key, node.value, newBuckets);
node = node.next;
}
}
buckets = newBuckets;
}
public V get(K key){
int index = getIndex(key, buckets.length);
Node<K,V> node = buckets[index];
if(node == null) return null;
while(node != null){
if(node.key.hashCode() == key.hashCode() && (node.key == key || node.key.equals(key))){
return node.value;
}else{
node = node.next;
}
}
return null;
}
public void remove(K key){
int index = getIndex(key, buckets.length);
Node<K,V> node = buckets[index];
if(node == null) return;
Node<K,V> pre = null;
while(node != null){
if(node.key.hashCode() == key.hashCode() && (node.key == key || node.key.equals(key))){
Node<K,V> next = node.next;
if(pre == null){
//表示删除的是头结点
buckets[index] = next;
}else{
pre.next = next;
}
size--;
return;
}else{
pre = node;
node = node.next;
}
}
return;
}
public int getSize(){
return size;
}
static class Student{
private String name;
private Integer age;
public Student(){
}
public Student(String name,Integer age){
this.name = name;
this.age = age;
}
public int hashCode(){
return 100;
}
public String getName(){
return name;
}
}
public static void main(String[] args) {
//MyHashMap<Integer,Integer> map = new MyHashMap<>(3);
Student s1 = new Student("yyn", 20);
Student s2 = new Student("yyn", 222);
MyHashMap<Student,Integer> map = new MyHashMap<>(3);
map.put(s1, 1);
map.put(s2, 2);
System.out.println(map.size);
System.out.println("s1:"+map.get(s1));
System.out.println("s2:"+map.get(s2));
map.remove(s2);
System.out.println(map.size);
System.out.println("s1:"+map.get(s1));
System.out.println("s2:"+map.get(s2));
System.out.println(map.buckets.length);
}
}
快手二面 使用Java手写简易HashMap
于 2023-08-22 20:01:58 首次发布