哈希表
哈希表是一种数据结构,不是算法
一个需求:新员工报道,将该员工的信息加入(id,性别,年龄,。。。)输入该员工的id时,要求找到该员工的所有信息
要求:不使用数据库,尽量节省内存,速度越快越好 ————哈希表(散列)
一级缓存,或者还有有二级缓存
1 import java.util.Hashtable; 2 import java.util.Scanner; 3 4 public class HashTableDemo { 5 public static void main(String[] args) { 6 //创建哈希表 7 HashTab hashTab = new HashTab(7); 8 //写一个简单菜单 9 String key = ""; 10 Scanner scanner = new Scanner(System.in); 11 while (true){ 12 System.out.println("add:添加雇员"); 13 System.out.println("list:显示雇员"); 14 System.out.println("find:查找雇员"); 15 System.out.println("exit:退出系统"); 16 key = scanner.next(); 17 switch (key){ 18 case "add": 19 System.out.println("输入id"); 20 int id = scanner.nextInt(); 21 System.out.println("输入名字"); 22 String name = scanner.next(); 23 //创建雇员 24 Emp emp = new Emp(id, name); 25 hashTab.add(emp); 26 break; 27 case "list": 28 hashTab.list(); 29 break; 30 case "find": 31 System.out.println("请输入要查找的id"); 32 id = scanner.nextInt(); 33 hashTab.findEmpById(id); 34 break; 35 case "exit": 36 scanner.close(); 37 System.exit(0); 38 default: 39 break; 40 } 41 } 42 43 } 44 45 } 46 47 48 //哈希表HashTable 管理多条链表 49 class HashTab{ 50 private EmpLinkedList[] empLinkedListArray; 51 private int size;//表示有多少条链表 52 //构造器 53 public HashTab(int size){ 54 this.size = size; 55 //初始化empLinkedListArray 56 empLinkedListArray = new EmpLinkedList[size]; 57 //这时不要忘记分别初始化每个链表 58 // 59 for (int i = 0; i < size; i++) { 60 empLinkedListArray[i] = new EmpLinkedList(); 61 } 62 63 } 64 65 //添加雇员 66 public void add(Emp emp){ 67 //根据员工的id,得到该员工应该加入到哪条链表 68 int empLinkedListNO = hashFun(emp.id); 69 //将emp 添加到对应的链表中 70 empLinkedListArray[empLinkedListNO].add(emp); 71 } 72 //遍历所有链表 73 public void list(){ 74 for (int i = 0; i < size; i++) { 75 empLinkedListArray[i].list(i); 76 } 77 } 78 //编写散列函数,使用一个简单取模法 79 public int hashFun(int id){ 80 return id % size; 81 } 82 83 //根据输入id查找雇员 84 public void findEmpById(int id){ 85 //使用散列函数到哪条链表查找 86 int empLinkedLisNO = hashFun(id); 87 Emp emp = empLinkedListArray[empLinkedLisNO].findEmpById(id); 88 if (emp!= null){ 89 System.out.printf("在第%d条链表中找到雇员id=%d\n",(empLinkedLisNO+1),id); 90 }else { 91 System.out.println("在哈希表中,没有找到该雇员"); 92 } 93 } 94 95 } 96 97 98 //创建EmpLinkedList,表示链表 99 class EmpLinkedList{ 100 //头指针,执行第一个Emp,因此我们这个链表的head是直接指向第一个Emp 101 private Emp head;//默认null 102 //添加雇员到链表 103 //说明 104 //!.假定当添加雇员时,id是自增,即id的分配总是从小到大 105 //因此将该雇员直接加入到本链表最后位置 106 public void add(Emp emp){ 107 //如果是添加第一个雇员 108 if (head == null){ 109 head = emp; 110 return; 111 } 112 //如果不是第一个雇员,则使用一个辅助指针帮助定位到最后 113 Emp curEmp = head; 114 while (true){ 115 if (curEmp.next == null){ 116 break; 117 } 118 curEmp = curEmp.next; 119 } 120 //退出时直接将emp加到最后 121 curEmp.next = emp; 122 123 } 124 //遍历链表的雇员信息 125 public void list(int no){ 126 if (head == null){//链表为空 127 System.out.println("第"+(no+1)+"链表为空"); 128 return; 129 } 130 System.out.print("第"+(no+1) 131 +"链表的信息为"); 132 Emp curEmp = head; 133 while (true){ 134 System.out.printf("id = %d name = %s \t",curEmp.id,curEmp.name); 135 if (curEmp.next == null){ 136 break; 137 } 138 curEmp = curEmp.next; 139 } 140 System.out.println(); 141 } 142 //根据id查找雇员 143 public Emp findEmpById(int id){ 144 //判断链表是否为空 145 if (head == null){ 146 System.out.println("链表为空"); 147 return null; 148 } 149 //辅助指针 150 Emp curEmp = head; 151 while (true){ 152 if (curEmp.id == id){//找到 153 break;//这时curEmp指向要查找的雇员 154 } 155 //退出 156 if (curEmp.next == null){ 157 curEmp = null; 158 break; 159 } 160 curEmp = curEmp.next; //移后 161 } 162 return curEmp; 163 164 } 165 } 166 // 167 168 169 //表示一个雇员 170 class Emp{ 171 public int id; 172 public String name; 173 public Emp next;//默认为null 174 175 public Emp(int id, String name) { 176 this.id = id; 177 this.name = name; 178 179 } 180 }