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;
        //初始化empLiskedListArray
        empLiskedListArray = 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);

    }

    //遍历所有的链表,遍历hashtable
    public 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();
    }
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

逆向案例十二——看准网企业信息json格式的信息

网址&#xff1a;【全国公司排行|排名榜单|哪家好】-看准网 打开开发者工具——刷新——网络——XHR——下滑页面加载新的页面——找到数据包 发现参数加密&#xff0c;返回的数据也进行了加密 按关键字在下方搜索 kiv进入第一个js文件 ctrlf打开文件里面的搜索框继续搜kiv找到…

多模态系列-综述Video Understanding with Large Language Models: A Survey

本文是LLM系列文章,针对《Video Understanding with Large Language Models: A Survey》的翻译。 论文链接:https://arxiv.org/pdf/2312.17432v2.pdf 代码链接:https://github.com/yunlong10/Awesome-LLMs-for-Video-Understanding 大型语言模型下的视频理解研究综述 摘要…

替换空格(替换特定字符)

&#x1f600;前言 在字符串处理中&#xff0c;经常会遇到需要替换特定字符的情况。本文将介绍一道经典的字符串替换问题&#xff1a;将字符串中的空格替换成 “%20”。我们将探讨一种高效的解决方法&#xff0c;通过倒序遍历字符串来实现原地替换&#xff0c;避免额外空间的开…

吴恩达:AI 智能体工作流

热门文章推荐&#xff1a; &#xff08;1&#xff09;《为什么很多人工作 3 年 却只有 1 年经验&#xff1f;》&#xff08;2&#xff09;《一文掌握大模型提示词技巧&#xff1a;从战略到战术巧》&#xff08;3&#xff09;《AI 时代&#xff0c;程序员的出路在何方&#xff1…

Python+Yolov8框选位置目标识别人数统计计数

程序示例精选 PythonYolov8框选位置目标识别人数统计计数 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《PythonYolov8框选位置目标识别人数统计计数》编写代码&#xff0c;代码整洁&#…

深度探索Sketch:功能、历程、替代软件及技巧一览

Sketch 它是一个适合所有设计师的矢量绘图应用程序。矢量绘图也是设计网页、图标和界面的最佳方式。但除了矢量编辑的功能外&#xff0c;我们还增加了一些基本的位图工具&#xff0c;如模糊和颜色校正。 为什么选择Sketch Sketch 它是为图标设计和界面设计而生的。它是一个优…

职场新变革:AI赋能ICT劳动力联盟的行动与展望

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【活动创作】未来AI技术方面会有哪些创业机会

放假期间突然看到这个活动创作&#xff0c;觉得很有意思&#xff0c;既然如此&#xff0c;我就先让AI来回答一下吧&#xff0c;哈哈 1、文心一言 首先来看看文心一言的回答&#xff1a; 2、讯飞星火 然后来看看讯飞星火的回答&#xff1a; 3、个人感受 最后来说说给人感受吧&am…

美国CPC认证是什么?为什么必须办理CPC认证呢?

美国CPC认证&#xff0c;全称为Childrens Product Certificate&#xff0c;是儿童产品认证的意思。它主要针对的是在美国市场销售的儿童产品&#xff0c;如玩具、家具、童车、餐椅、床上用品等。CPC认证要求产品安全性高&#xff0c;符合美国加州65、16 CFR等法规要求&#xff…

【Linux】达梦数据库安装部署(附详细图文)

目录 一、安装前的准备工作 1.检查操作系统配置 &#xff08;1&#xff09;获取系统位数 getconf LONG_BIT &#xff08;2&#xff09;查看操作系统release信息 cat /etc/system-release &#xff08;3&#xff09;查询系统名称 uname -a &#xff08;4&#xff09;查看操…

Filter

文章目录 Filter快速入门url-pattern生命周期FilterConfigFilterChain 过滤器链执行顺序 Filter Filter 过滤器它是 JavaWeb 的三大组件之一(Servlet 程序、Listener 监听器、Filter 过滤器)。 Filter 过滤器它的作用是&#xff1a;拦截请求&#xff0c;过滤响应。 快速入门 创…

撸代码时,有哪些习惯一定要坚持?

我从2011年开始做单片机开发&#xff0c;一直保持以下撸代码的习惯。 1.做好代码版本管理 有些人&#xff0c;喜欢一个程序干到底&#xff0c;直到实现全部的产品功能&#xff0c;我以前做51单片机的项目就是这样。 如果功能比较多的产品&#xff0c;我不建议这样做&#xff0…

【CSS】背景模糊,不模糊主体文字

问题 背景模糊&#xff0c;不模糊文本 效果图 t1 t2 t3 实现思路 自定义css变量存储图片地址&#xff0c;方便后期更改使用伪元素实现背景模糊达到不遮挡主体文本 transform: scale(1.5)吧图片放大1.5倍&#xff0c;避免设置背景模糊出现白边。 overflow: hidden 超出隐藏&…

摄影师-IP营第5期课程,帮助摄影师涨粉变现(39节课)

课程内容: 1_【直播】千万级营收的摄影师IP做对了什么?.mp4 2_【直播】第1课【流量来源】摄影师如何在小红书涨粉 接单变现?.mp4 3_【直播】第2课【私域成交】摄影师高粘性的朋友园信任打造体系.mp4 4_【直播】第3课【销售谈单】小白&社恐也能学会的摄影谈单术.mp4 …

API力量:用API技术为你的数据安全“上保险”

&#x1f680; API在数据安全领域的核心地位 随着数字化进程的狂飙突进&#xff0c;应用程序接口&#xff08;API&#xff09;已化身为企业内部、不同平台间以及用户交互的关键纽带。它们不仅是数据流动与共享的驱动引擎&#xff0c;更是守护数据安全的重要防线。其中&#x…

【Mathematical Model】基于Python实现随机森林回归算法特征重要性评估线性拟合

前段时间在做遥感的定量反演&#xff0c;所以研究了一下回归算法&#xff0c;由于之前发的几篇博文都是定义好基础方程进行拟合的&#xff0c;不太满足我的需求。所以研究了一下随机森林回归的算法&#xff0c;之前使用随机森林都是做分类&#xff0c;这次做了回归算法也算是补…

微信聊天记录恢复只需简单3招,快速找回聊天内容!

各种社交软件早已深深融入我们的日常生活&#xff0c;无论是与亲朋好友的闲聊&#xff0c;还是与同事伙伴的工作沟通&#xff0c;都离不开它们的陪伴。然而&#xff0c;有时由于误操作、系统更新或手机故障等原因&#xff0c;我们可能会不小心删除了重要的聊天记录&#xff0c;…

基于SSM+Jsp+Mysql的弹幕视频网站

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

UVC紫外杀菌灯珠-消毒杀菌应用解决方案

随着疾病传播的频繁发生以及人们对卫生健康的重视&#xff0c;有效的杀菌措施&#xff0c;更好的消毒杀菌技术越来越重要&#xff0c;为此&#xff0c;工采网提供一系列UVC紫外杀菌灯珠产品&#xff0c;为客户提供适应不同功能应用的UVC杀菌方案。 UVC紫外线杀菌是一种高效、安…

在不同操作系统中搭建Python编程环境

1 在不同操作系统中搭建Python编程环境 1.1 在Linux系统中搭建Python编程环境 1. 检查Python版本 在你的系统中运行应用程序Terminal&#xff08;如果你使用的是Ubuntu&#xff0c;可按Ctrl Alt T&#xff09;&#xff0c;打开一个终端窗口。为确定是否安装了Python&…