十一、哈希表(散列)
应用场景
有一个公司,当右新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址…),当输入该员工id时,要求查到该员工索引信息
要求:不适用数据库,尽量节省内存,速度越快越好
基本介绍
也叫散列表,是根据关键码值二直接进行访问的数据结构。也就是说,它通过把关键码值映射到一个表中一个位置来访问记录,以加快查找速度。这个映射函数叫散列函数,存放记录的数组叫做散列表
实现缓存层
定义哈希表可以自己实现缓存层:
- 数组+链表
- 数组+二叉树
11.1 使用哈希表管理雇员信息
需求
有一个公司,当右新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址…),当输入该员工id时,要求查到该员工索引信息
要求:不适用数据库,尽量节省内存,速度越快越好
思路分析
- 创建员工类,实现存储员工信息
- 创建链表头指针指向第一个员工
- 创建哈希表,建立数组属性,存储这些链表;创建散列函数,决定id对应的链表(数组的元素)
- 通过哈希表实现增删改查
代码实现
package com.why.a;
/**
* @Description TODO 哈希表
* @Author why
* @Date 2020/11/3 18:00
* Version 1.0
**/
public class HashTable {
public static void main(String[] args) {
hashTable hashTable = new hashTable(3);
Employee e1 = new Employee(1,"why","男",14,"兰州");
Employee e2 = new Employee(2,"why","男",14,"兰州");
hashTable.add(e1);
hashTable.add(e2);
hashTable.list();
}
}
/**
* 管理多条链表
*/
class hashTable{
int size;
private HashLinkedList[] hashLinkedListsArr;
public hashTable(int size) {
this.size = size;
hashLinkedListsArr = new HashLinkedList[size];
//不要忘记分别初始化每一条链表
for (int i = 0; i < size; i++) {
hashLinkedListsArr[i] = new HashLinkedList();
}
}
/**
* 添加雇员
* @param node
*/
public void add(Employee node){
//根据员工id,得到该员工应该添加到哪条链表
int empLinkedListNo = hasFun(node.getId());
//将employee添加到对应的链表中
hashLinkedListsArr[empLinkedListNo].insert(node);
}
/**
* 遍历hash表
*/
public void list(){
for (int i = 0; i < hashLinkedListsArr.length; i++) {
hashLinkedListsArr[i].show();
}
}
/**
* 编写散列函数,使用简单的取模法
* @param id
* @return
*/
public int hasFun(int id){
return id % size;
}
}
class HashLinkedList {
//头指针
private Employee head = new Employee();
/**
* 添加功能
*/
public void insert(Employee employee){
Employee temp = head;
while (true){
if (temp == null){
break;
}
temp = temp.getNext();
}
temp.setNext(employee);
}
/**
* 删除
* @param id
*/
public void delete(int id){
if (head == null){
System.out.println("空");
}
Employee temp = head;
while (true){
if (temp.getId() == id){
temp.setNext(temp.getNext());
break;
}
temp = temp.getNext();
}
}
/**
* 更新
* @param employee
*/
public void update(Employee employee){
if (head == null){
System.out.println("空");
}
Employee temp = head;
while (true){
if (temp.getId() == employee.getId()){
temp.setId(employee.getId());
temp.setName(employee.getName());
temp.setAddress(employee.getAddress());
temp.setAge(employee.getAge());
temp.setGender(employee.getGender());
break;
}
temp = temp.getNext();
}
}
/**
* 根据id查询一条记录
* @param id
* @return
*/
public Employee findById(int id){
if (head.getNext() == null){
System.out.println("空");
}
Employee temp = head;
while (true){
if (temp.getId() == id){
Employee employee = temp;
return employee;
}
temp = temp.getNext();
}
}
/**
* 遍历显示
*/
public void show(){
//判空
if (head == null){
System.out.println("空");
}
Employee temp = head;
while (true){
if (temp == null){
break;
}
//输出节点信息
System.out.println(temp);
temp = temp.getNext();
}
}
}
class Employee {
private int id;
private String name;
private String gender;
private int age;
private String address;
private Employee next;
public Employee() {
}
public Employee(int id, String name, String gender, int age, String address) {
this.id = id;
this.name = name;
this.gender = gender;
this.age = age;
this.address = address;
}
public Employee getNext() {
return next;
}
public void setNext(Employee next) {
this.next = next;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}