-
1 定义
-
2 为什么需要散列这种数据结构
-
3 实例分析
=======================================================================
散列表(Hash table,也叫哈希表),是根据 Key-Value
而直接进行访问的数据结构。也就是说,它通过把Key-Value
映射到表中一个位置来访问记录,以加快查找的速度。
这个映射函数叫做散列函数,存放记录的数组叫做哈希表。
==================================================================================
为什么使用哈希表呢?在平常的数据管理中,我们常常将数据放在数据库中,但数据库实际上是一个硬盘,如果直接从 Java 程序向数据库中存取数据的速度会比较慢,这个时候,我们有两种方法来解决这个问题。
-
使用现在的缓存产品,比如Redis或者Mencache;
-
自己写哈希表。
之所以这两种方式方式会更快,是因为它们是存储在内存中的,相比于硬盘,存取速度会更快。
哈希表(Hashtab)由以下部分组成,存放链表的数组,以及存放数据的链表,而数据存放的链表在数据中的索引则由散列函数得到。 图解如下:
=========================================================================
实例:将某学校的学生信息存入到某一数据结构中,信息包括 id、姓名,实现该系统的增、查与遍历。要求: 不使用数据库,速度越快越好。
思路分析:见上图。
代码实现:
import java.util.Scanner;
/**
- 需求:利用哈希表(散列表)的方法来管理学生信息,不使用数据库的方式
*/
public class StudentManageWindow {
public static void main(String[] args) {
//创建哈希表
Hashtab hashTab = new Hashtab(7);
//写一个简单的菜单
String key = “”;
Scanner scanner = new Scanner(System.in);
while(true) {
System.out.println(“add: 添加雇员”);
System.out.println(“list: 显示雇员”);
System.out.println(“find: 查找雇员”);
System.out.println(“exit: 退出系统”);
key = scanner.next();
switch (key) {
case “add”:
System.out.println(“输入id”);
int id = scanner.nextInt();
System.out.println(“输入名字”);
String name = scanner.next();
//创建 学生
Student student = new Student(id, name);
hashTab.add(student);
break;
case “list”:
hashTab.list();
break;
case “find”:
System.out.println(“请输入要查找的id”);
id = scanner.nextInt();
hashTab.findStudentById(id);
break;
case “exit”:
scanner.close();
System.exit(0);
default:
break;
}
}
}
}
/**
- 创建Hashtab 管理多条链表
*/
class Hashtab {
private StudentLinkedList[] studentLinkedListArr;
//表示有多少条链表
private int size;
//构造器
public Hashtab(int size) {
this.size = size;
//初始化StudentLinkedList
studentLinkedListArr = new StudentLinkedList[size];
//这时不要忘了分别初始化每个链表
for(int i = 0; i < size; i++) {
studentLinkedListArr[i] = new StudentLinkedList();
}
}
/**
-
添加学生
-
@param student
*/
public void add(Student student) {
//根据员工的id ,得到该员工应当添加到哪条链表
int studentID = hashFun(student.id);
//将student添加到对应的链表中
studentLinkedListArr[studentID].add(student);
}
/**
-
遍历所有的链表,遍历hashtab
*/
public void list() {
for(int i = 0; i < size; i++) {
studentLinkedListArr[i].list(i);
}
}
/**
-
根据输入的id,查找雇员
-
@param id
*/
public void findStudentById(int id) {
//使用散列函数确定到哪条链表查找
int studentID = hashFun(id);
Student student = studentLinkedListArr[studentID].findStudentById(id);
if(student != null) {//找到
System.out.printf(“在第%d条链表中找到 雇员 id = %d\n”, (studentID + 1), id);
}else{
System.out.println(“在哈希表中,没有找到该雇员~”);
}
}
/**
-
编写散列函数, 使用一个简单取模法
-
@param id
-
@return
*/
public int hashFun(int id) {
return id % size;
}
}
/**
-
描述:用于存放学生的链表
-
头指针,指向当前链表的第一个雇员(相当于都节点也放数据)
*/
class StudentLinkedList {
//默认null
private Student head;
//添加雇员到链表
//说明
/**1. 假定,当添加雇员时,id 是自增长,即id的分配总是从小到大,因此我们将该雇员直接加入到本链表的最后即可
- @param student
*/
public void add(Student student) {
//如果是添加第一个雇员
if(head == null) {
head = student;
return;
}
//如果不是第一个雇员,则使用一个辅助的指针,帮助定位到最后
Student curStudent = head;
while (curStudent.next != null) {
//说明到链表最后
curStudent = curStudent.next;
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后总结
搞定算法,面试字节再不怕,有需要文章中分享的这些二叉树、链表、字符串、栈和队列等等各大面试高频知识点及解析
最后再分享一份终极手撕架构的大礼包(学习笔记):分布式+微服务+开源框架+性能优化
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
nimg.cn/images/e5c14a7895254671a72faed303032d36.jpg" alt=“img” style=“zoom: 33%;” />
最后总结
搞定算法,面试字节再不怕,有需要文章中分享的这些二叉树、链表、字符串、栈和队列等等各大面试高频知识点及解析
最后再分享一份终极手撕架构的大礼包(学习笔记):分布式+微服务+开源框架+性能优化
[外链图片转存中…(img-55twdBZo-1713714551104)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!