@Java 300 学习总结

HashMap底层采用实现采用了哈希表,结合了“数组和链表”。

原理如图

一、定义HashMap类。

首先需要定义一个节点来存储数据,构成链表结构。

public class Node {
int hash;
Object key;
Object value;
Node next;
}
public class ggHashMap {
Node[] table; //位桶数组,用于存放链表的第一个节点
int size;
public ggHashMap() {
super();
table = new Node[16]; //默认初始为16
} public static void main(String[] args) {
ggHashMap m1 = new ggHashMap();
System.out.println();
}
}

二、实现put方法,往HashMap里添加元素

每一个节点存放进HashMap里,首先根据key继续Hash值,以此确定插入的位置。


public int myHash(int v,int length) {
return v&(length -1);//根据Hash值与位桶数组长度,进行位运算,保证插入元素的随机
//位运算与取模运算效果相同,但是效率更高
} public void put(Object key, Object value) {
Node newNode = new Node();
newNode.hash = myHash(key.hashCode(),table.length);
//根据key的值取hash值,hashCode()为对象默认存在的方法
newNode.key = key;
newNode.value = value;
newNode.next = null; Node temp = table[newNode.hash];//指向要插入的数组位置
Node iterLast = null;//正在遍历的最后一个元素
boolean keyRepeat = false;//判定元素key值是否相同被覆盖
if(temp == null) { //数组元素为空
table[newNode.hash] = newNode;
}
else { //不为空的情况
while(temp!=null) { //遍历该链表 //判断key是否重复
if(temp.key.equals(key)) {
keyRepeat = true;
temp.value = value;
break; //找到重复结束遍历
}else {
iterLast = temp; //iterLast跟着temp向后移一位
temp = temp.next;
}
}
if(!keyRepeat) {
iterLast.next = newNode; //没有发现重复,最后一位的next,指向新节点
}
}
}

三、实现toString方法

利用可以自动扩增的StringBuilder对象,遍历每个节点,可实现数据的HashMap的字符串。

public String toString() {
StringBuilder sb = new StringBuilder("{");
for(int i = 0;i < table.length;i++) {
Node temp = table[i];
while(temp!=null) {
sb.append(temp.key+":"+temp.value + ",");
temp = temp.next;
}
}
sb.setCharAt(sb.length()-1, '}');//将最后一个,号,转为}
return sb.toString();
}

四、实现get方法,根据key获得value

根据key值计算hash数值,指针指向数组索引值和hash值相等的节点,遍历该节点的链表,找到key值相等的节点,返回value值

public Object get(Object key) {
int hash = myHash(key.hashCode(), table.length);
Object value = null;
Node temp = table[hash];
while(temp!=null) {
if(temp.key.equals(key)) {
value = temp.value;
break;
}else {
temp = temp.next;
}
}
return value;
}

五、增加泛型

public class Node2<K,V> {
int hash;
K key;
V value;
Node2 next;
}
public class ggHashMap4<K,V> {
public V get(K key) { }
public void put(K key, V value) { }
}

Java手写简单HashMap一(包括增加,查找,toString,泛型)的更多相关文章

  1. Java手写简单Linkedlist一(包括增加,插入,查找,toString,remove功能)

    @Java300 学习总结 一.自定义节点 LinkList底层为双向链表.特点为查询效率低,但增删效率高,线程不安全. 链表数据储存在节点,且每个节点有指向上个和下个节点的指针. 创建ggLinke ...

  2. 利用Java手写简单的httpserver

    前言: 在看完尚学堂JAVA300中讲解如何实现一个最简单的httpserver部分的视频之后, 一.前置知识 1.HTTP协议 当前互联网网页访问主要采用了B/S的模式,既一个浏览器,一个服务器,浏 ...

  3. 教你如何使用Java手写一个基于链表的队列

    在上一篇博客[教你如何使用Java手写一个基于数组的队列]中已经介绍了队列,以及Java语言中对队列的实现,对队列不是很了解的可以我上一篇文章.那么,现在就直接进入主题吧. 这篇博客主要讲解的是如何使 ...

  4. java 手写 jvm高性能缓存

    java 手写 jvm高性能缓存,键值对存储,队列存储,存储超时设置 缓存接口 package com.ws.commons.cache; import java.util.function.Func ...

  5. java手写多级缓存

    多级缓存实现类,时间有限,该类未抽取接口,目前只支持两级缓存:JVM缓存(实现 请查看上一篇:java 手写JVM高性能缓存).redis缓存(在spring 的 redisTemplate 基础实现 ...

  6. 不使用Tomcat,手写简单的web服务

    背景: 公司使用的YDB提供了http的查询数据库服务,直接通过url传入sql语句查询数据-_-||.ydb的使用参照:https://www.cnblogs.com/hd-zg/p/7115112 ...

  7. 手写简单call,apply,bind

    分析一下call的使用方法:call是显示绑定this指向,然后第一个参数是你所指向的this对象,后面跟着多个参数,以逗号隔开 function sum(num1,num2){ return num ...

  8. 手写简单的jq雪花飘落

    闲来无事,准备写个雪花飘落的效果,没有写太牛逼的特效,极大的简化了代码量,这样容易读取代码,用起来也很简单,对于那些小白简直是福利啊,简单易读易学.先直接上代码吧,然后再一一讲解,直接复制粘贴就可以拿 ...

  9. Java:手写幼儿园级线程安全LRU缓存X探究影响命中率的因素

    最近遇到一个需求,需要频繁访问数据库,但是访问的内容只是 id + 名称 这样的简单键值对. 频繁的访问数据库,网络上和内存上都会给数据库服务器带来不小负担. 于是打算写一个简单的LRU缓存来缓存这样 ...

随机推荐

  1. sick 激光

    sick10:TiM561-2050101https://www.sick.com/cn/zh/detection-and-ranging-solutions/2d-lidar-/tim5xx/tim ...

  2. ELK日志解决方案

    1.方案整体设计 FileBeats+Logstash+ElasticSearch+Kibana 1)ElasticSearch 简称ES,用来做日志数据的存储,当然也可以存储其他数据, ES是互联网 ...

  3. BufferedWriter中write与close函数使用

    BufferedWriter 是一个缓冲字符输出流,可以将要输出的内容先缓冲到一个字符数组中,等字符数组满了才一次性写到输出流内,默认的字符数组长度为8192.使用BufferedWriter 时需要 ...

  4. 查看memcache版本

    window: cmd中用telnet 127.0.0.1 11211这样的命令连接上memcache,然后直接输入stats就可以得到memcache服务器的版本. 注意:memcache的默认端口 ...

  5. Python3 编程之字符串处理

    Python3 编程之字符串处理 在编程中最常见的任务就是字符串的处理,So,学好字符串的使用非常重要 一.变量的定义规范 Python中声明变量时,要符合以下规则为准: 只能使用数字.字母.下划线组 ...

  6. 安装vue模板时,选择webpack-simple还是Webpack?

    选用模板常用的是webpack与webpack-simple.webpack-simple是基于Webpack@2.1.0-beta.25进行配置的版本,而webpack模板则是基于Webpack ^ ...

  7. [转][echarts]地图轮播

    代码片断: 来自:https://blog.csdn.net/qq_36947128/article/details/90899564 function Play(){ chart.dispatchA ...

  8. Flask-分开Models解决循环引用

    Flask-分开Models解决循环引用 在之前我们测试中,所有语句都在同一个文件中,但随着项目越来越大,管理起来有所不便,所以将Models分离.基本的文件结构如下 \—–app.py\—–mode ...

  9. redis分布式锁练习【我】

    package redis; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; public class ...

  10. CVR并发写入测试

    CVR并发写入测试 测试环境: 主机:DELL Optiplex 790 系统:Windows7SP1 64bit CPU:i5-2500 3.3GB 4核 内存:8GB 硬盘:希捷 7200rpm ...