自制hashmap
package jjj;
public class MyHashMap<K, V> {
//initialization capacity
private int capacity = 10;
//total entities
private int size = 0;
private Entity<K, V>[] entities = null;
@SuppressWarnings("unchecked")
public MyHashMap() {
entities = new Entity[capacity];
}
public void put(K key, V value) {
if (key == null) {
throw new RuntimeException("The key is null");
}
reHash();
Entity<K, V> newEntity = new Entity<K, V>(key, value);
put(newEntity, this.entities, this.capacity);
}
private void put(Entity<K, V> newEntity, Entity<K, V>[] entities, int capacity) {
int index = newEntity.getKey().hashCode() % capacity;
Entity<K, V> entity = entities[index];
Entity<K, V> firstEntity = entities[index];
if (entity == null) {
entities[index] = newEntity;
size++;
} else {
if (newEntity.getKey().equals(entity.getKey())) {//Find the same key for the first entity, if find then replace the old value to new value
newEntity.setNext(entity.getNext());
newEntity.setPre(entity.getPre());
if (entity.getNext() != null) {
entity.getNext().setPre(newEntity);
}
entities[index] = newEntity;
} else if (entity.getNext() != null) {
while (entity.getNext() != null) {//Find the same key for all the next entity, if find then replace the old value to new value
entity = entity.getNext();
if (newEntity.getKey().equals(entity.getKey())) {
newEntity.setPre(entity.getPre());
newEntity.setNext(entity.getNext());
if (entity.getNext() != null) {
entity.getNext().setPre(newEntity);
}
entities[index] = newEntity;
return;
}
}
//Cannot find the same key, then insert the new entity at the header
newEntity.setNext(firstEntity);
newEntity.setPre(firstEntity.getPre());
firstEntity.setPre(newEntity);
entities[index] = newEntity;
size++;
} else {
//Cannot find the same key, then put the new entity in head
newEntity.setNext(firstEntity);
firstEntity.setPre(newEntity);
entities[index] = newEntity;
size++;
}
}
}
public V get(K key) {
if (key == null) {
throw new RuntimeException("The key is null");
}
int index = key.hashCode() % capacity;
Entity<K, V> entity = entities[index];
if (entity != null) {
if (entity.getKey().equals(key)) {
return entity.getValue();
} else {
entity = entity.getNext();
while (entity != null) {
if (entity.getKey().equals(key)) {
return entity.getValue();
}
entity = entity.getNext();
}
}
}
return null;
}
public void remove(K key) {
if (key == null) {
throw new RuntimeException("The key is null");
}
int index = key.hashCode() % capacity;
Entity<K, V> entity = entities[index];
if (entity != null) {
if (entity.getKey().equals(key)) {
if (entity.getNext() != null) {//remove the first entity
entity.getNext().setPre(entity.getPre());
entities[index] = entity.getNext();
entity = null;
} else {//empty this index
entities[index] = null;
}
size--;
} else {
entity = entity.getNext();
while (entity != null) {
if (entity.getKey().equals(key)) {
if (entity.getNext() != null) {
entity.getPre().setNext(entity.getNext());
entity.getNext().setPre(entity.getPre());
entity = null;
} else {
//release the found entity
entity.getPre().setNext(null);
entity = null;
}
size--;
return;
}
entity = entity.getNext();
}
}
}
}
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < capacity; i++) {
sb.append("index=").append(i).append("[");
boolean hasEntity = false;
Entity<K, V> entity = entities[i];
if (entity != null) {
hasEntity = true;
}
while (entity != null) {
sb.append("[").append(entity.getKey()).append("=").append(entity.getValue()).append("]").append(",");
entity = entity.getNext();
}
if (hasEntity) {
sb.deleteCharAt(sb.length() - 1);
}
sb.append("]\n");
}
return sb.toString();
}
/**
* Simple re-hash strategy, if the size is bigger than capacity, then do re-hash action
*/
private void reHash() {
if (size >= capacity) {
int newCapacity = capacity * 2;
@SuppressWarnings("unchecked")
Entity<K, V>[] newEntities = new Entity[newCapacity];
for (int i = 0; i < capacity; i++) {
Entity<K, V> entity = entities[i];
while (entity != null) {
put(entity, newEntities, newCapacity);
entity = entity.getNext();
}
}
this.capacity = newCapacity;
this.entities = newEntities;
}
}
public static void main(String[] args) {
MyHashMap<String, String> map = new MyHashMap<String, String>();
map.put("one", "1");
map.put("two", "2");
map.put("three", "3");
map.put("four", "4");
map.put("five", "5");
map.put("six", "6");
map.put("seven", "7");
map.put("eight", "8");
map.put("nine", "9");
map.put("ten", "10");
System.out.println(map.get("one"));
System.out.println(map.get("two"));
System.out.println(map.get("three"));
System.out.println(map.get("four"));
System.out.println(map.get("five"));
System.out.println(map.get("six"));
System.out.println(map.get("seven"));
System.out.println(map.get("eight"));
System.out.println(map.get("nine"));
System.out.println(map.get("ten"));
System.out.println(map.toString());
map.remove("nine");
map.remove("three");
System.out.println(map.get("one"));
System.out.println(map.get("two"));
System.out.println(map.get("three"));
System.out.println(map.get("four"));
System.out.println(map.get("five"));
System.out.println(map.get("six"));
System.out.println(map.get("seven"));
System.out.println(map.get("eight"));
System.out.println(map.get("nine"));
System.out.println(map.get("ten"));
System.out.println(map.toString());
}
}
class Entity<K, V> {
private K key;
private V value;
private Entity<K, V> pre;
private Entity<K, V> next;
public Entity(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public Entity<K, V> getPre() {
return pre;
}
public void setPre(Entity<K, V> pre) {
this.pre = pre;
}
public Entity<K, V> getNext() {
return next;
}
public void setNext(Entity<K, V> next) {
this.next = next;
}
}
自制hashmap的更多相关文章
- 自制数据结构(容器)-java开发用的最多的ArrayList和HashMap
public class MyArrayList<E> { private int capacity = 10; private int size = 0; private E[] val ...
- Spring 依赖注入控制反转实现,及编码解析(自制容器)
定义: 在运行期,由外部容器动态的将依赖对象动态地注入到组件中. 两种方式: 手工装配 -set方式 -构造器 -注解方式 自动装配(不推荐) 1利用构造器 2set方法注入 dao: package ...
- OpenFaaS实战之八:自制模板(maven+jdk8)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- HashMap的工作原理
HashMap的工作原理 HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道HashTable和HashMap之间 ...
- 计算机程序的思维逻辑 (40) - 剖析HashMap
前面两节介绍了ArrayList和LinkedList,它们的一个共同特点是,查找元素的效率都比较低,都需要逐个进行比较,本节介绍HashMap,它的查找效率则要高的多,HashMap是什么?怎么用? ...
- Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结
2017年的秋招彻底结束了,感觉Java上面的最常见的集合相关的问题就是hash--系列和一些常用并发集合和队列,堆等结合算法一起考察,不完全统计,本人经历:先后百度.唯品会.58同城.新浪微博.趣分 ...
- 学习Redis你必须了解的数据结构——HashMap实现
本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文链接博客园蜗牛 cnblogs.com\tdws . 首先提供一种获取hashCode的方法,是一种比较受欢迎的方式,该方法参照了一位园友的 ...
- HashMap与HashTable的区别
HashMap和HashSet的区别是Java面试中最常被问到的问题.如果没有涉及到Collection框架以及多线程的面试,可以说是不完整.而Collection框架的问题不涉及到HashSet和H ...
随机推荐
- OnXXX函数与XXX事件的关系
OnPaint是Control类中的方法,Paint是事件,Paint是用于改变部分显示用比较合适,实际上Paint事件在OnPaint中被调用,如果你重写OnPaint但是不调用base.OnPai ...
- mysql数据库切分
一.数据的垂直切分概念:数据的垂直切分,也可以称之为纵向切分.将不同的表分散到不同的数据库主机中.一个应用系统,总体功能肯定是由很多个功能模块所组成的,而每一个功能模块所需要的数据对应到数据库中就是一 ...
- Mysql批量导入约束报错
SET foreign_key_checks = 0; 禁用外键,在文件顶部加 SOURCE dump_file_name; 进行SQL执行 SET foreign_key_checks ...
- 29 Socketserver和 ftp
一.Socketserver #服务端 import socketserver class KnightServer(socketserver.BaseRequestHandler): def han ...
- Codeforces Round #364 (Div. 1) (差一个后缀自动机)
B. Connecting Universities 大意: 给定树, 给定2*k个点, 求将2*k个点两两匹配, 每个匹配的贡献为两点的距离, 求贡献最大值 单独考虑每条边$(u,v)$的贡献即可, ...
- Educational Codeforces Round 47 (Rated for Div. 2)F. Dominant Indices 线段树合并
题意:有一棵树,对于每个点求子树中离他深度最多的深度是多少, 题解:线段树合并快如闪电,每个节点开一个权值线段树,递归时合并即可,然后维护区间最多的是哪个权值,到x的深度就是到根的深度减去x到根的深度 ...
- python-day21--random模块
>>> import random #随机整数 >>> random.randint(1,5) # 大于等于1且小于等于5之间的整数 >>> ra ...
- Shell脚本的学习(一)
Shell脚本的学习(一) 一)代码式shell脚本简介 1.下载 Xshell 5 建一个文件夹 mkdri home/data ; 1)查看一个在data里建一个1.sh 查看是否建立成功. 2) ...
- eclipse编译zookeeper源码
使用版本zookeeper-3.4.6.jar 从官网下载zookeeper-3.4.6.tar.gz,解压缩到 D:\tools 文件夹,目录结构如下图. 1. Eclipse新建java工程: 2 ...
- JavaScript学习总结(五)——Javascript中==和===的区别
一.JavaScript"=="的作用 当==两边的内容是字符串时,则比较字符串的内容是否相等. 当==两边的内容是数字时,则比较数字的大小是否相等. 当==两边的内容是对象或者是 ...