# 实现

O(1)

O(n)

O(n)

O(n)

O(1)

O(1)

```public class Main {

public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
String key = "code" + i;
System.out.println(key.hashCode());
}
}
}```

```94834659
94834660
94834661
94834662
94834663
94834664
94834665
94834666
94834667
94834668```

```public class Main {

public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
String key = "code" + i;
int hashCode = key.hashCode();
int index = hashCode % 8;
System.out.println(index);
}
}
}```

```3
4
5
6
7
0
1
2
3
4```

# 代码

```/**
* 手写简单的hashMap（1.7版）
*
* @author DHB
*/
public class MyHashMap<K, V> {

/**
* 元素表
*/
private Entry<K, V>[] table;
/**
* 容量
*/
private static final Integer CAPACITY = 8;
/**
* 大小
*/
private int size = 0;

public MyHashMap() {
this.table = new Entry[CAPACITY];
}

/**
* 获取大小
*
* @return 大小
*/
public int size() {
return this.size;
}

/**
* 根据key获取value
*
* @param key jey
* @return 元素
*/
public V get(K key) {
int index = obtainIndex(key);
for (Entry<K, V> entry = table[index]; entry != null; entry = entry.next) {
if (entry.k.equals(key)) {
return entry.v;
}
}
return null;
}

/**
* 插入，当存在这个key的时候会替换，并且返回
*
* @param key   key
* @param value value
* @return 旧的元素
*/
public V put(K key, V value) {
int index = obtainIndex(key);
for (Entry<K, V> entry = table[index]; entry != null; entry = entry.next) {
if (entry.k.equals(key)) {
V oldValue = entry.v;
entry.v = value;
return oldValue;
}
}
return null;
}

/**
* 添加Entry
*
* @param key   key
* @param value value
* @param index 下标位置
*/
private void addEntry(K key, V value, int index) {
table[index] = new Entry(key, value, table[index]);
size++;
}

/**
* 通过key获取插入的位置
*
* @param key key
* @return 获取位置
*/
private int obtainIndex(K key) {
int hashCode = key.hashCode();
return hashCode % 8;
}

/**
* 链表数据结构
*
* @param <K> key
* @param <V> value
*/
class Entry<K, V> {

public Entry(K k, V v, Entry<K, V> next) {
this.k = k;
this.v = v;
this.next = next;
}

private K k;
private V v;
/**
* 指向下一个元素
*/
private Entry<K, V> next;
}

}```

# 总结

• HashMap的键值可以为Null吗？原理是什么？
• HashMap扩容机制是怎么样的，JDK7和JDK8有什么不同？
• JDK8中的HashMap有哪些改动？
• JDK8中为什么要使用红黑树？
• 为什么重写对象的Equal方法时，要重写HashCode方法，跟HashMap有什么关系吗？
• HashMap是线程安全的吗？遇到ConcurrentModificationException异常吗？为什么？出现怎么解决？
• 在使用HashMap的过程中我们应该注意些什么问题？

0 条评论

• ### Jvm中各种内存溢出情况分析

oom即OutOfMemoryError，出现这个报错的主要原因是内存空间不足以装下数据导致抛出异常。要探讨JVM出现oom的情况，首先要了解下jvm的内存模型...

• ### JVM参数记录

JVM 参数设置 Is there a way to get which classes a ClassLoader has loaded?

• ### 1搭建nacos

nacos的官方仓库地址:https://github.com/alibaba/nacos.git

• ### 【Redis】Redis常用命令

expire key seconds 当超过过期时间，会自动删除，key在seconds秒后过期 expireat key timest...

• ### Redis学习二（数据操作）.

在 redis-cli 中使用中文时，必须打开 --raw 选项，才能正常显示中文。

• ### Redis内存数据库操作命令详解

rename(oldname, newname)：将key由oldname重命名为newname，若newname存在则删除newname表示的key

• ### Redis常用命令、5种数据类型的内部编码实现以及实用场景

相信绝大部分人，应该是99%的人都知道Redis的5种的基本类型、它们分别是：字符串、哈希、列表、集合、有序集合，就如同下图这样：

• ### vue和react中循环key的作用

没用过react开发项目，但想来跟vue在循环渲染中key的作用应该原理是一样的。循环在没有使用key的时候，vue会警告。但是这个key的作用是什么。

• ### Redis命令与配置

slaveof  127.0.0.1 6379(设置Mater的Host以及Port)

• ### Redis命令总结及其基础知识讲述

Redis拥有其他数据库不具备的数据结构，又拥有内存存储（这使得redis的速度非常快），远程操作（使得redis可以与多个客户端和服务器进行连接）、持久化...