@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. 前端逼死强迫症系列之css

    一.编写css样式 1.ID选择器 由于ID唯一,所以也是写多遍. <head> <style> #i1{ background-color: #2459a2; height: ...

  2. springboot 出现 org.hibernate.LazyInitializationException: could not initialize proxy

    org.hibernate.LazyInitializationException: could not initialize proxy [com.example.shop.dataobject.U ...

  3. CF1208B

    CF1208B 题意: 给出n个数字,找出最小的一端连续区间进行删除操作,使其剩余元素不含重复元素,求要删除的最小区间长度 解法: 删除子段后,前缀和后缀保持不变,可能长度为0.让我们修复不包含任何重 ...

  4. opensuse tumbleweed中安装code

    在opensuse上启用snaps并安装visual studio code snaps是一个应用程序,运行在很多流行linux发行版上, 其所有依赖项都打包在一个构建中,并且会自动更新并能优雅地回滚 ...

  5. DataTable 转换为List

           注意table 列的参数类型,若不为string 需要详细声明 如 typeof(Int32)          public static IList<T> Convert ...

  6. Python下划线命名模式

  7. SQL-W3School-基础:SQL UPDATE 语句

    ylbtech-SQL-W3School-基础:SQL UPDATE 语句 1.返回顶部 1. Update 语句 Update 语句用于修改表中的数据. 语法: UPDATE 表名称 SET 列名称 ...

  8. python小白之字典使用笔记

    Python 字典(Dictionary)   字典是一种可变容器模型,且可存储任意类型对象. 每个键值 key=>value 对,用冒号 : 分割 每个键值对之间用逗号 , 分割 整个字典包括 ...

  9. 关于axios如何在请求头添加参数

    vm.$http.post(apiUrl.refundOrder, data,{ headers:{ 'lz-shopid':vm.orderRecords.shopId } }).then(res ...

  10. 获取当前运行的exe路径

    void GetAppPath(CString& path) { TCHAR str[] = {}; GetModuleFileName(NULL,str,); wchar_t *pszPos ...