/**
* 01.自定义一个hashmap
* 02.实现put增加键值对,实现key重复时替换key的值
* 03.重写toString方法,方便查看map中的键值对信息
* 04.实现get方法,根据键对象获取相应的值对象
* 05.封装、增加泛型
* 06.remove方法、数组扩容方法暂缺
* 07.remove方法已增加
*/

package cn.study.lu.four;

public class HashMap <K,V>{

node3[] table;
int size;
public HashMap() {
table = new node3[16];//一般为2的整数次幂
}

public void put(K key,V value) {//定义新的节点对象
//如果要完善,还需要考虑数组扩容,稍后增加

node3 newnode = new node3();
newnode.hash = myHash(key.hashCode(), table.length);
newnode.key = key;
newnode.value = value;
newnode.next = null;

node3 temp = table[newnode.hash];
node3 last = null;
boolean keyRepeat = false;

if (temp == null) {
table[newnode.hash] = newnode;
size++;
}else {//temp不为空的情况下,遍历table[newnode.hash]

while (temp!=null) {
if (temp.key == newnode.key) {
keyRepeat = true;
temp.value = newnode.value;
break;
}else {
last = temp;
temp = temp.next;
}

}
if (!keyRepeat) {
last.next = newnode;
size++;
}

}

}

public int myHash(int v,int length) {
return v&(length-1);// 也可以用 v % length,但是二者结果不一样,都可以实现散列
}

public String toString() {
StringBuilder sb = new StringBuilder("{");
//遍历数组
for (int i = 0; i < table.length; i++) {
node3 temp = table[i];
//遍历链表
while (temp!=null) {
sb.append(temp.key+":"+temp.value+",");
temp = temp.next;
}

}

sb.setCharAt(sb.length()-1, '}');
return sb.toString();
}

public V get(K key) {
int hash = myHash(key.hashCode(), table.length);
V value = null;

if (table[hash] != null) {
node3 temp = table[hash];

while (temp!=null) {
if (temp.key.equals(key)) {
value = (V)temp.value;
break;
}else {
temp = temp.next;
}

}
}

return value;
}

public void remove(K key) {
int hash = myHash(key.hashCode(), table.length);
node3 temp = table[hash];
node3 copy = null;

if (temp == null) {
return;
}else {
if (temp.next == null) {
table[hash] = null;
temp = null;
size--;
}else {
while (temp.key!=key) {
copy = temp;
temp = temp.next;
System.out.println(temp.value);
}
copy.next = temp.next;
temp = null;
size--;
}

}
}

public static void main(String[] args) {
HashMap<Integer,String> m = new HashMap<Integer,String>();
m.put(1, "aaa");
m.put(2, "bbb");
m.put(3, "ccc");
m.put(4, "ddd");
m.put(5, "eee");

m.put(53, "111");
m.put(69, "222");
m.put(85, "333");

m.put(3, "fff");

m.remove(53);

System.out.println(m);
System.out.println(m.get(69));
}

}

class node2{
int hash;
Object key;
Object value;
node2 next;

}

class node3<K,V>{
int hash;
K key;
V value;
node3 next;
}

手写hashmap算法的更多相关文章

  1. 手写HashMap,快手面试官直呼内行!

    手写HashMap?这么狠,面试都卷到这种程度了? 第一次见到这个面试题,是在某个不方便透露姓名的Offer收割机大佬的文章: 这--我当时就麻了,我们都知道HashMap的数据结构是数组+链表+红黑 ...

  2. [纯C#实现]基于BP神经网络的中文手写识别算法

    效果展示 这不是OCR,有些人可能会觉得这东西会和OCR一样,直接进行整个字的识别就行,然而并不是. OCR是2维像素矩阵的像素数据.而手写识别不一样,手写可以把用户写字的笔画时间顺序,抽象成一个维度 ...

  3. 手写HASHMAP

    手写HASHMAP const int MAXN=10010; const int HASH=10100;            //需要hash的数的总个数最大值 struct HASHMAP { ...

  4. 手写HashMap实践

    1.什么是HashMap 2.源码分析 3.手写实现 4.不足 一.什么是HashMap hash散列 将一个任意长度通过某种算法(hash函数算法)换成一个固定值 map: 地图x,y 存储 总结: ...

  5. 08.手写KNN算法测试

    导入库 import numpy as np from sklearn import datasets import matplotlib.pyplot as plt 导入数据 iris = data ...

  6. 用C实现单隐层神经网络的训练和预测(手写BP算法)

    实验要求:•实现10以内的非负双精度浮点数加法,例如输入4.99和5.70,能够预测输出为10.69•使用Gprof测试代码热度 代码框架•随机初始化1000对数值在0~10之间的浮点数,保存在二维数 ...

  7. 手写KMeans算法

    KMeans算法是一种无监督学习,它会将相似的对象归到同一类中. 其基本思想是: 1.随机计算k个类中心作为起始点. 将数据点分配到理其最近的类中心. 3.移动类中心. 4.重复2,3直至类中心不再改 ...

  8. 手写k-means算法

    作为聚类的代表算法,k-means本属于NP难问题,通过迭代优化的方式,可以求解出近似解. 伪代码如下: 1,算法部分 距离采用欧氏距离.参数默认值随意选的. import numpy as np d ...

  9. Javascript 手写 LRU 算法

    LRU 是 Least Recently Used 的缩写,即最近最少使用.作为一种经典的缓存策略,它的基本思想是长期不被使用的数据,在未来被用到的几率也不大,所以当新的数据进来时我们可以优先把这些数 ...

随机推荐

  1. HDU6599 (字符串哈希+回文自动机)

    题意: 求有多少个回文串的前⌈len/2⌉个字符也是回文串.(两组解可重复)将这些回文串按长度分类,分别输出长度为1,2,...,n的合法串的数量. 题解:https://www.cnblogs.co ...

  2. 清北学堂2019NOIP提高储备营DAY4

    今天只有一上午,讲的东西不多,这里就整理一下高精的东西,数论部分请见my blog 高精度: 先讲一讲进制问题:十进制的二进制表示:以10为例, 10的二进制表示为1010 10的三进制表示为101 ...

  3. tjuthesis 图标题左对齐修改办法

    图标题格式默认是居中的. 将 format 文件里定义图表标题样式部分的 \centering 删去,可变为左对齐. 如下: %% 定制浮动图形和表格标题样式\makeatletter\long\de ...

  4. 002-localStorage和sessionStorage操作

    一.概述 HTML5 提供了两种在客户端存储数据的新方法: localStorage - 没有时间限制的数据存储 一直存在除非用户手动清除缓存;是基于域的,任何该域下的所有页面都可访问localSto ...

  5. SpringBoot整合Lintener

    1.通过扫描完成Lintener组件的注册 1.1编写Listener /** * springboot整合Lintener 方式一 * 在web.xml中如何配置Listener * <lis ...

  6. DataGridView数值列和日期列

    本文转自:http://www.cnblogs.com/conexpress/p/5923324.html 在使用DataGridView编辑数据的时候,编辑的单元格一般会显示为文本框,逻辑值和图片会 ...

  7. ecshop注册用户增加手机验证功能

    1.去掉“用户名”注册 a.去掉提交 user_passport.dwt页面去掉 <input name="username" type="text" s ...

  8. json-server-----》基本使用

    [WangQi]---json-server---基本使用   一.前后端并行开发的痛点 前端需要等待后端开发完接口以后 再根据接口来完成前端的业务逻辑 二.解决方法 在本地模拟后端接口用来测试前端效 ...

  9. jQuery源码分析系列——来自Aaron

    jQuery源码分析系列——来自Aaron 转载地址:http://www.cnblogs.com/aaronjs/p/3279314.html 版本截止到2013.8.24 jQuery官方发布最新 ...

  10. CentOSLinux系统中Ansible自动化运维的安装以及利用Ansible部署JDK和Hadoop

    Ansible 安装和配置 Ansible 说明 Ansible 官网:https://www.ansible.com/ Ansible 官网 Github:https://github.com/an ...