Java 哈希表

一、哈希表的由来

我们的java程序通过访问数据库来获取数据,但是当我们对数据库所查询的信息进行大量分析后得知,我们要查询的数据满足二八定律,一般数据库的数据基本存储在磁盘当中。这使得每次查询数据将变得无比缓慢。为此我们可以将经常查询的数据放置在内存当中,在内存当中设置缓存,我们java程序先去缓存当中去查询数据,这样将大大节省我们的数据查询时间。

缓存可以分为两种一种是市面上的存储产品,例如redis.也或者我们自己可以开发一个缓存(哈希表)。

二、哈希表的数据结构

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

散列函数:是用来确定我们每一个值得存储在哪一个链表之上。

三、为了了解什么是哈希表

我们先来看如下的一道题:

有一个公司,当有新的员工来报道时,需要将该员工的信息加入(id,性别,年龄,住址,...),当输入该用户id时,需要查询到该员工的所有信息。

要求:不使用数据库,尽量节省内存,速度越快越好 --> 哈希表

分析清楚上边的题以后我们来用代码将其实现。

首先分析这个代码有哪些组成。

根据拆分我们可以知道一个哈希表是由节点组成链表,每一个链表都存放在数据当中的每个节点当中,如下图。

代码实现

主要代码

/*** 定义该类表示一个雇员*/
public class Employee {public int id;public String name;public Employee next; // next默认为空//定义构造函数public Employee(int id, String name) {this.id = id;this.name = name;}
}
/*** 定义该类表示链表*/
public class EmpLiskedList {// 定义头指针,指向第一个Emp对象public Employee head;/*** 添加雇员到链表* 说明:* 我们这个方法采用的是尾插法将新插入的数据放置到尾部* 1.判断头指针是否为空* 2.如果不是第一个雇员,则使用一个辅助指针,帮助定位到最后* @param employee*/public void add(Employee employee){//判断头指针是否为空if(head == null){head = employee;return;}//如果不是第一个雇员,则使用一个辅助指针,帮助定位到最后Employee tempEmp = head;while (true){if(tempEmp.next == null){ //说明链表到了最后break;}tempEmp = tempEmp.next; //后移}//将employee加入到链表tempEmp.next = employee;}/*** 遍历链表的雇员信息* 说明:* 1. 首先需要判断链表是否为空* 2. 借助辅助指针进行遍历* @param i 这是第几条链表*/public void list(int i){if(head == null){ // 说明链表为空System.out.println("链表为空");return;}//定义一个值表示链表的大小和int count = 1;//定义辅助指针Employee tempEmp = head;while (true){System.out.println("id:="+tempEmp.id+" "+"name:="+tempEmp.name);//判断是否到了最后节点if(tempEmp.next == null){System.out.println("这是第"+i+"条链表,长度为"+count);break;}tempEmp = tempEmp.next;//后移count ++;}}}
/*** 该类的主要作用是管理散列表*/
public class HashTab {// 定义散列表private EmpLiskedList[] empLiskedListArray;//定义散列表的大小private int size;// 构造器public HashTab(int size){this.size = size;//初始化empLiskedListArrayempLiskedListArray = new EmpLiskedList[size];// 一个小坑,这个地方不要忘记分别初始化每个链表,// 我们的散列表当中每个位置还是空的for (int i=0;i<size;i++){empLiskedListArray[i] = new EmpLiskedList();}}//编写散列函数,使用一个简单取模法public int hash(int id){return id % size;}// 添加雇员public void add(Employee employee){//根据员工的id,得到该员工应该添加到那一条链表int num = hash(employee.id);// 将emp添加到对应的链表当中去empLiskedListArray[num].add(employee);}//遍历所有的链表,遍历hashtablepublic void list(){for (int i=0;i<size;i++){empLiskedListArray[i].list(i);}}}

测试类

public class Test {public static void main(String[] args) {HashTab hashTab = new HashTab(8);Employee employee1 = new Employee(1,"张三1");Employee employee2 = new Employee(4,"张三4");Employee employee3 = new Employee(6,"张三6");Employee employee4 = new Employee(8,"张三8");Employee employee5 = new Employee(10,"张三10");Employee employee6 = new Employee(11,"张三11");Employee employee7 = new Employee(15,"张三15");Employee employee8 = new Employee(16,"张三16");Employee employee9 = new Employee(18,"张三18");Employee employee10 = new Employee(20,"张三20");hashTab.add(employee1);hashTab.add(employee2);hashTab.add(employee3);hashTab.add(employee4);hashTab.add(employee5);hashTab.add(employee6);hashTab.add(employee7);hashTab.add(employee8);hashTab.add(employee9);hashTab.add(employee10);hashTab.list();}
}

 谢谢你的阅读,点个赞吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/595832.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode代码记录(第一个出现两次的字母

目录 1. 题目&#xff1a;2. 我的代码&#xff1a;小结&#xff1a; 1. 题目&#xff1a; 给你一个由小写英文字母组成的字符串 s &#xff0c;请你找出并返回第一个出现 两次 的字母。 注意&#xff1a; 如果 a 的 第二次 出现比 b 的 第二次 出现在字符串中的位置更靠前&…

【随笔】Git 高级篇 -- 分离 HEAD(十一)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

【unity小技巧】unity最完美的CharacterController 3d角色控制器,实现移动、跳跃、下蹲、奔跑、上下坡、物理碰撞效果,复制粘贴即用

最终效果 文章目录 最终效果前言为什么使用CharacterControllerSimpleMove和Move如何选择&#xff1f;1. SimpleMove2. Move 配置CharacterController参数控制相机移动跳跃方式一方式二 下蹲处理下坡抖动问题实现奔跑和不同移速控制完整代码补充&#xff0c;简单版本 实现物理碰…

很详细的单应矩阵分解R、t过程

很详细的单应矩阵分解R、t过程 附赠自动驾驶学习资料和量产经验&#xff1a;链接 已有多种方法将单应矩阵H分解为R、t&#xff0c;在《Deeper understanding of the homography decomposition for vision-based control》一文中介绍了三种方法&#xff1a; O. Faugeras and F.…

Docker实战教程 第1章 Linux快速入门

2-1 Linux介绍 为什么要学Linux 三个不得不学习 课程需要&#xff1a;Docker开发最好在Linux环境下。 开发需要&#xff1a;作为一个后端程序员&#xff0c;是必须要掌握Linux的&#xff0c;这是找工作的基础门槛。 运维需要&#xff1a;在服务器端&#xff0c;主流的大型服…

【操作系统】STM32-操作系统——持续更新

【操作系统】STM32-操作系统——持续更新 文章目录 前言一、ucosii二、freertos1.介绍2.移植 总结 前言 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、ucosii UCOSII移植到STM32F103C8T6上之移植记录&#xff08;一&#xff09; UCOSII移植到ST…

C++之类和对象(上)

目录 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 4.1访问限定符 4.2 类的两种定义方式 第一种&#xff1a; 第二种&#xff1a; 4.3封装 5.类的实例化 6.类对象模型 1.面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;…

京东云服务器地域和可用区选择方法,多因素考虑攻略

京东云服务器地域如何选择&#xff1f;根据地理位置就近选择地域。京东云主机地域支持北京、宿迁、上海和广州&#xff0c;华北地区用户选择北京地域&#xff0c;华东地区用户可以选择上海或宿迁地区&#xff0c;南方用户选择广州地域。云服务器吧yunfuwuqiba.com整理京东云主机…

IP地址获取不到的原因是什么?

在数字化时代的今天&#xff0c;互联网已成为我们日常生活和工作中不可或缺的一部分。而IP地址&#xff0c;作为互联网通信的基础&#xff0c;其重要性不言而喻。然而&#xff0c;有时我们可能会遇到IP地址获取不到的问题&#xff0c;这会给我们的网络使用带来诸多不便。那么&a…

BPMNJS 在原生HTML中的引入与使用

BPMNJS 在HTML中的引入与使用 在网上看到的大多是基于vue使用BPMN的示例或者教程&#xff0c;竟然没有在HTML使用的示例&#xff0c;有也是很简单的介绍核心库的引入和使用&#xff0c;并没有涉及到扩展库。于是简单看了下&#xff0c;真的是一波三折&#xff0c;坎坎坷坷。不…

Spring源码分析(@Configuration)

文章目录 Spring源码分析&#xff08;Configuration&#xff09;一、ConfigurationClassPostProcessor1、主要作用和特点2、执行的时机3、BeanFactoryPostProcessor4、BeanDefinitionRegistryPostProcessor5、ConfigurationClassPostProcessor1&#xff09;postProcessBeanDefi…

使用 Copilot 重新定义Forms表单创建

您好&#xff0c;Microsoft 365 copilot订阅用户&#xff01;很高兴与大家分享&#xff0c;您现在可以在表单中利用 Copilot 更轻松地构建高质量且设计精良的调查、表单和民意调查。 使用 Copilot 重新定义表单创建 只需向 Copilot 描述您想要构建的表单&#xff0c;您就可以…