Live2D
Fork me on GitHub

25、哈希表

来源:https://www.bilibili.com/video/BV1B4411H76f?p=77

一、问题/需求

希望在不使用数据库的情况下,存储一个公司的雇员信息(id,姓名等),尽量节省内存,速度越快越好。这时候可以用哈希表。

哈希表:也叫散列表,通过key-value的形式对数据进行访问,可以加快查找速度。具体来说,它的结构是数组+链表(或数组+二叉树)的形式。把关键码值(例如员工ID)映射到数组中,对数组下对应的链表进行存储或访问。这样的映射函数也叫散列函数。(常用的映射方式:关键码值对数组大小取余)

哈希表可以用作简单的java程序与SQL之间的缓存。

 

 

二、实现一个哈希表,存储雇员信息

  1 public class HashTable {
  2     public static void main(String[] args) {
  3         HashTab hashTab = new HashTab(7);
  4 
  5         String key = "";
  6         Scanner scanner = new Scanner(System.in);
  7         while (true){
  8             System.out.println();
  9             System.out.println("add:添加雇员");
 10             System.out.println("show:显示雇员");
 11             System.out.println("select:查找雇员");
 12             System.out.println("exit:退出系统");
 13 
 14             key = scanner.next();
 15             switch (key){
 16                 case "add":
 17                     System.out.println("输入ID");
 18                     int id  = scanner.nextInt();
 19                     System.out.println("输入name");
 20                     String name  = scanner.next();
 21                     Emp emp = new Emp(id, name);
 22                     hashTab.add(emp);
 23                     break;
 24                 case "show":
 25                     hashTab.show();
 26                     break;
 27                 case "select":
 28                     System.out.println("输入ID");
 29                     id  = scanner.nextInt();
 30                     hashTab.selecyById(id);
 31                     break;
 32                 case "exit":
 33                     scanner.close();
 34                     System.exit(0);
 35                 default:
 36                    break;
 37             }
 38         }
 39     }
 40 }
 41 
 42 //哈希表
 43 class HashTab{
 44     //创建一个数组,数组内容的类型为下面的链表
 45     private EmpLinkedList[] empLinkedLists;
 46     private int size;
 47 
 48     public HashTab(int size) {
 49         this.size = size;
 50         empLinkedLists = new EmpLinkedList[size];
 51         for (int i = 0; i < size; i++) {
 52             empLinkedLists[i] = new EmpLinkedList();
 53         }
 54     }
 55 
 56     //散列函数(映射方法)
 57     public int hashFunction(int id){
 58         return id % size;
 59     }
 60 
 61     //添加雇员
 62     public void add(Emp emp){
 63         int hashNo = hashFunction(emp.id);
 64         empLinkedLists[hashNo].add(emp);
 65     }
 66 
 67     //展示所有雇员
 68     public void show(){
 69         for (int i = 0; i < size; i++) {
 70             empLinkedLists[i].show(i);
 71         }
 72     }
 73 
 74     //查找雇员
 75     public void selecyById(int id){
 76         int hashNo = hashFunction(id);
 77         Emp emp = empLinkedLists[hashNo].selectById(id);
 78         if(emp == null){
 79             System.out.println("没有找到雇员");
 80         }else {
 81             System.out.printf("在第%d条链表中找到了雇员,id = %d",hashNo+1,id);
 82             System.out.println();
 83         }
 84     }
 85 }
 86 
 87 //可以存放雇员的链表
 88 class EmpLinkedList{
 89     private Emp head = null;
 90 
 91     //增加雇员
 92     public void add(Emp emp){
 93         if(head == null){
 94             head = emp;
 95             return;
 96         }
 97         Emp curEmp = head;
 98         while (true){
 99             if(curEmp.next == null){
100                 break;
101             }
102             curEmp = curEmp.next;
103         }
104         curEmp.next = emp;
105     }
106 
107     //展示链表下的所有雇员 no:关键码值映射出来的数组内容
108     public void show(int no){
109         if(head == null){
110             System.out.println("第"+no+"条链表为空");
111             return;
112         }
113         System.out.println("第"+no+"条链表的内容为:");
114         Emp curEmp = head;
115         while (true){
116             System.out.print("id="+curEmp.id+",name="+curEmp.name);
117             if(curEmp.next == null){
118                 break;
119             }
120             curEmp = curEmp.next;
121         }
122         System.out.println();
123     }
124 
125     //通过id查找雇员信息
126     public Emp selectById(int id){
127         if (head == null){
128             System.out.println("链表为空");
129             return null;
130         }
131         Emp curEmp = head;
132         while (true){
133             if(curEmp.id == id){
134                 break;
135             }
136             if(curEmp.next == null){
137                 curEmp = null;
138                 break;
139             }
140             curEmp = curEmp.next;
141         }
142         return curEmp;
143     }
144 }
145 
146 
147 //雇员类
148 class Emp{
149     public int id;
150     public String name;
151     public Emp next;
152 
153     public Emp(int id, String name) {
154         this.id = id;
155         this.name = name;
156     }
157 }

测试及结果

add:添加雇员
show:显示雇员
select:查找雇员
exit:退出系统
show
第0条链表为空
第1条链表为空
第2条链表为空
第3条链表为空
第4条链表为空
第5条链表为空
第6条链表为空

add:添加雇员
show:显示雇员
select:查找雇员
exit:退出系统
add
输入ID
5
输入name
aa

add:添加雇员
show:显示雇员
select:查找雇员
exit:退出系统
add
输入ID
6
输入name
bb

add:添加雇员
show:显示雇员
select:查找雇员
exit:退出系统
add
输入ID
7
输入name
cc

add:添加雇员
show:显示雇员
select:查找雇员
exit:退出系统
show
第0条链表的内容为:
id=7,name=cc
第1条链表为空
第2条链表为空
第3条链表为空
第4条链表为空
第5条链表的内容为:
id=5,name=aa
第6条链表的内容为:
id=6,name=bb

add:添加雇员
show:显示雇员
select:查找雇员
exit:退出系统
select
输入ID
7
在第1条链表中找到了雇员,id = 7

add:添加雇员
show:显示雇员
select:查找雇员
exit:退出系统

 

posted @ 2020-06-20 17:43  -小二黑-  阅读(175)  评论(0编辑  收藏  举报