1.HashMap的介绍
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。
HashMap 是无序的,即不会记录插入的顺序。
HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口。
HashMap 的 key 与 value 类型可以相同也可以不同,可以是字符串(String)类型的 key 和 value,也可以是整型(Integer)的 key 和字符串(String)类型的 value。
2.HashMap的实现
1.添加元素
/**
* 往MyMap中添加元素
*
* @param key key值
* @param value key值对应的value值
* @return 所添加的元素
*/
public Object put(Object key, Object value) {
//获取key的hashCode值
int hashValue = key.hashCode();
//获取key的hashCode值对应的数组下标的值
int index = hashValue % nodes.length;
//判断是否需要扩容
if (size == nodes.length * 0.75) {
//扩容操作
capacity();
}
//如果index对应的链表不为空
Node node = nodes[index];
//遍历index对应的链表
while (node != null) {
//如果链表上已经存在该key值则进行替换key的value
if (key.equals(node.key)) {
Object oldValue = node.value;
//替换key的value值
node.value = value;
return oldValue;
}
node = node.next;
}
//index对应的链表为空
Node node1 = nodes[index];
//新增数组节点
nodes[index] = new Node(key, value, node1);
size++;
return null;
}
2.移除元素
/**
* 移除MyMap中的一个数据
*
* @param key key值
* @return 移除key值对应的value值
*/
public Object remove(Object key) {
//获取key的hashCode值
int hashValue = key.hashCode();
//获取key的hashCode值对应的数组下标的值
int index = hashValue % nodes.length;
Node node = nodes[index];
if (node != null) {
//如果index上存在数据
if (node.key.equals(key)) {
//key对应上链表的第一个节点
nodes[index] = node.next;
size--;
return node.value;
} else {
//如果key不对应链表的第一个节点
while (null != node.next) {
//当前节点的下一个节点不为空
if (key.equals(node.next.key)) {
Object oldValue = node.next.value;
node.next = node.next.next;
size--;
return oldValue;
}
node = node.next;
}
}
}
//index上不存在数据
return null;
}
3.判断是否包含某个key值
/**
* 判断MyMap是否包含某个key
*
* @param key 传入一个key
* @return 包含传入的key返回true,否则返回false
*/
public boolean containsKey(Object key) {
//获取key的hashCode值
int hashValue = key.hashCode();
//获取key的hashCode值对应的数组下标的值
int index = hashValue % nodes.length;
//遍历数组下标对应的链表
Node node = nodes[index];
while (node != null) {
if (key.equals(node.key)) {
//如果链表中存在与key相等的值
return true;
}
node = node.next;
}
return false;
}
4.获取key对应的value值
/**
* 获取key对应的value值
*
* @param key 传入一个key
* @return key对应的value值,没有则返回null
*/
public Object get(Object key) {
//获取key的hashCode值
int hashValue = key.hashCode();
//获取key的hashCode值对应的数组下标的值
int index = hashValue % nodes.length;
//遍历数组下标对应的链表
Node node = nodes[index];
while (node != null) {
if (key.equals(node.key)) {
//如果链表中存在与key相等的值且该key的hashCode值也相等
//返回key对应的value
return node.value;
}
node = node.next;
}
//链表中不存在则返回null
return null;
}
3.完整代码+测试用例
完整代码如下:
package practice;
public class MyHashMap {
public static void main(String[] args) {
MyMap myMap = new MyMap();
myMap.put("a", 1);
myMap.put("b", 2);
myMap.put("c", 3);
myMap.put("d", 4);
myMap.put("e", 5);
myMap.put("f", 6);
myMap.put("h", 7);
myMap.put("i", 8);
myMap.put("j", 9);
myMap.put("j", 10);
myMap.put("l", 11);
myMap.put("m", 12);
myMap.put("n", 13);
myMap.put("o", 14);
myMap.put("p", 15);
myMap.put("qw", 16);
myMap.put("as", 17);
myMap.put("wt", 18);
myMap.put("cs", 19);
myMap.put("go", 20);
// System.out.println(myMap.nodes.length);
System.out.println("size:" + myMap.getSize());
// System.out.println("isEmpty:" + myMap.isEmpty());
// System.out.println("key对应的值:" + myMap.get("r"));
System.out.println("containsKey:" + myMap.containsKey("a"));
System.out.println("remove的key对应的value:" + myMap.remove("a"));
System.out.println("size:" + myMap.getSize());
System.out.println("containsKey:" + myMap.containsKey("a"));
// myMap.clear();
// System.out.println("size:" + myMap.getSize());
// System.out.println("isEmpty:" + myMap.isEmpty());
// System.out.println("key对应的值:" + myMap.get("r"));
}
}
class MyMap {
//无参构造函数
public MyMap() {
}
//含Node[]的有参构造函数
public MyMap(Node[] nodes) {
this.nodes = nodes;
}
/**
* 定义的一个单链表类
*/
static class Node {
Object key;
Object value;
Node next;
public Node(Object key, Object value, Node next) {
this.key = key;
this.value = value;
this.next = next;
}
}
//起始数组长度
private final int length = 16;
//初始化一个数组
Node[] nodes = new Node[length];
//用来记录MyMap中存放的数据个数
private int size = 0;
/**
* 获取MyMap的大小
*
* @return MyMap的大小
*/
public int getSize() {
return this.size;
}
/**
* 判断MyMap是否为空
*
* @return MyMap为空返回true,否则返回false
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 判断MyMap是否包含某个key
*
* @param key 传入一个key
* @return 包含传入的key返回true,否则返回false
*/
public boolean containsKey(Object key) {
//获取key的hashCode值
int hashValue = key.hashCode();
//获取key的hashCode值对应的数组下标的值
int index = hashValue % nodes.length;
//遍历数组下标对应的链表
Node node = nodes[index];
while (node != null) {
if (key.equals(node.key)) {
//如果链表中存在与key相等的值
return true;
}
node = node.next;
}
return false;
}
/**
* 获取key对应的value值
*
* @param key 传入一个key
* @return key对应的value值,没有则返回null
*/
public Object get(Object key) {
//获取key的hashCode值
int hashValue = key.hashCode();
//获取key的hashCode值对应的数组下标的值
int index = hashValue % nodes.length;
//遍历数组下标对应的链表
Node node = nodes[index];
while (node != null) {
if (key.equals(node.key)) {
//如果链表中存在与key相等的值且该key的hashCode值也相等
//返回key对应的value
return node.value;
}
node = node.next;
}
//链表中不存在则返回null
return null;
}
/**
* 往MyMap中添加元素
*
* @param key key值
* @param value key值对应的value值
* @return 所添加的元素
*/
public Object put(Object key, Object value) {
//获取key的hashCode值
int hashValue = key.hashCode();
//获取key的hashCode值对应的数组下标的值
int index = hashValue % nodes.length;
//判断是否需要扩容
if (size == nodes.length * 0.75) {
//扩容操作
capacity();
}
//如果index对应的链表不为空
Node node = nodes[index];
//遍历index对应的链表
while (node != null) {
//如果链表上已经存在该key值则进行替换key的value
if (key.equals(node.key)) {
Object oldValue = node.value;
//替换key的value值
node.value = value;
return oldValue;
}
node = node.next;
}
//index对应的链表为空
Node node1 = nodes[index];
//新增数组节点
nodes[index] = new Node(key, value, node1);
size++;
return null;
}
/**
* 移除MyMap中的一个数据
*
* @param key key值
* @return 移除key值对应的value值
*/
public Object remove(Object key) {
//获取key的hashCode值
int hashValue = key.hashCode();
//获取key的hashCode值对应的数组下标的值
int index = hashValue % nodes.length;
Node node = nodes[index];
if (node != null) {
//如果index上存在数据
if (node.key.equals(key)) {
//key对应上链表的第一个节点
nodes[index] = node.next;
size--;
return node.value;
} else {
//如果key不对应链表的第一个节点
while (null != node.next) {
//当前节点的下一个节点不为空
if (key.equals(node.next.key)) {
Object oldValue = node.next.value;
node.next = node.next.next;
size--;
return oldValue;
}
node = node.next;
}
}
}
//index上不存在数据
return null;
}
/**
* 清空MyMap
*/
public void clear() {
Node[] nodes1 = new Node[nodes.length];
size = 0;
nodes = nodes1;
// if (nodes != null && size > 0) {
// size = 0;
// Arrays.fill(nodes, null);
// }
}
/**
* 数组扩容
*/
public void capacity() {
//定义一个新数组
Node[] newNode = new Node[nodes.length * 2];
//创建一个新的MyMap对象,将新数组存入对象
MyMap map = new MyMap(newNode);
//遍历原来的数组
for (Node value : nodes) {
if (value != null) {
//nodes[i]处存在链表就将链表put进新的MyMap对象中
Node node = value;
while (node != null) {
map.put(node.key, node.value);
node = node.next;
}
}
}
//最后将新的MyMap对象的nodes赋值给原来的nodes
nodes = map.nodes;
}
}
测试用例结果如下:
HashMap的实现到这里就结束啦!中途有任何问题可以再评论区留言,我会为你们解答。