用哈希表实现简单的缓存层

用哈希表实现简单的缓存层

问题:

有一个公司,当有新的员工来报道时,要求所有的员工信息录入电脑(id,性别,年龄,住址。。),当输入员工的id时,要求查到该员工的所有信息
要求:不使用数据库,尽量节省内存,速度越快越好------使用哈希表

问题分析

  1. 采用数组加链表的方式实现哈希表
  2. 建造三各类,Employ{int id,String name},EmployLinkedList{Employ head,增删改除的相关方法},HashTab{链表型数组,数组规模size,计算hash值的散列函数,操纵链表进行增删改除的相关方法},

代码实现:

  1. Employ类
public class Employ {
    public int id;
    public String name;
    public Employ next;
    //作为单向链表,必备包含下一个节点的索引信息

    public Employ(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public Employ() {
    }

    @Override
    public String toString() {
        return "Employ{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
  1. EmployLinkedList链表类
public class EmployLinkedList {
    //没有头结点
    private Employ head ;

    public boolean isEmpty(){
        if (head == null){
            return true;
        }else{
            return false;
        }
    }
    //增加元素
    public void add(Employ employ){
        if (isEmpty()){
            head = employ;
            return;
            //即使是没有返回值的语句,也是可以用return增加一个出口
            //然后就没有必要再设置else了
        }
        //不为空,就要找到尾结点,在尾结点处添加
        Employ curBoy = head;
        while (true) {
            if (curBoy.next == null) {
                break;
            }
            curBoy = curBoy.next;
        }
        curBoy.next = employ;

    }
    //遍历元素
    public void list(){
        //遍历元素,看看是否为空
        if (isEmpty()){
            System.out.println("链表为空");
            return;
        }
        Employ curBoy = head;
        while (true) {
            System.out.print("id为:" + curBoy.id + "name为:" + curBoy.name + ">>>");
            if (curBoy.next == null) {
                break;
            }
            curBoy = curBoy.next;
        }
        System.out.println();

    }
    //根据id直接查找出对应的雇员
    public Employ search(int id){
        //要用到索引,先判定是否为空
        if (isEmpty()){
            //System.out.println("链表为空,所查元素不存在");
            return head;
        }
        Employ temp = head;
        while (true) {
            //没有固定的序号,明确的次数,不用for
            if (temp.id == id) {
                return temp;
            }
            if (temp.next == null) {
                temp = null;
                return temp;
            }
            temp = temp.next;
        }
        //然后仅仅只有hashtab可以调用,在hashtab中说明相关的方法


    }
    //删除链表节点
    public void delete (int id){
        //删除结点判定是否为空
        if (isEmpty()){
            System.out.println("链表为空");
        }
        //如果不为空,查找待删除的元素
        if(search(id) == null){
            System.out.println("所要删除元素不存在");
        }else{
            Employ temp = head;
            boolean isFLag = false;
            while (true){
                //没有固定的序号,明确的次数,不用for
                if (temp.next == null){
                    break;
                }
                if (temp.next.id == id){
                    isFLag =true;
                    break;
                }
                temp = temp.next;
            }
            if (isFLag){
                temp.next = temp.next.next;
                System.out.println("成功删除");
            }else{
                if (head.id == id){
                    head = null;
                    System.out.println("成功删除");
                }else{
                    System.out.println("不存在");
                }

            }
        }

    }
}
  1. HashTab类以及测试方法
import java.util.Scanner;

public class HashTab {
    public static void main(String[] args) {
        HashTab hashTab = new HashTab(10);
        //写一个简单的菜单,提示各种信息
        String key = "";
        Scanner scan = new  Scanner(System.in);
        while(true){
            System.out.println("add:添加雇员");
            System.out.println("list:遍历雇员");
            System.out.println("search:查找雇员");
            System.out.println("delete:删除雇员");
            System.out.println("exit:退出");
            key = scan.next();
            switch (key){
                case "add":
                    System.out.println("please input the name");
                    String name = scan.next();
                    System.out.println("please input the id");
                    int id = scan.nextInt();
                    hashTab.add(new Employ(id,name));
                    break;
                case "list":
                    hashTab.list();
                    break;
                case "search":
                    System.out.println("please input the id");
                    int id2 = scan.nextInt();
                    hashTab.search(id2);
                    break;
                case "delete":
                    System.out.println("please input the id");
                    int id3 = scan.nextInt();
                    hashTab.delete(id3);
                    break;
                case "exit":
                    scan.close();
                    System.exit(0);
                default:
            }

        }
    }
    //创建hashTab管理多条链表
    private EmployLinkedList[] employLinkedListsArray;
    private int size;

    public HashTab(int size) {
        this.size = size;
        employLinkedListsArray = new EmployLinkedList[size];
        //这里是开辟了一个空间,但是没有给每一个数组的对象进行赋值,默认值都是null
        for (int i = 0 ;i < size;i ++){
            employLinkedListsArray[i] = new EmployLinkedList();
        }
    }
    //添加雇员
    public void add(Employ employ){
        int employLinkListArrayNo = hasNun(employ.id);
        employLinkedListsArray[employLinkListArrayNo].add(employ);
    }
    //根据雇员的关键值,就是id获取他的hash数值,从而给他进行对应的添加
    private int hasNun(int id){
        //取模法获取其对应的hash值
        return id % size;
    }
    //遍历
    public void list(){
        for(int i = 0; i < size;i ++){
            System.out.print("第" + i + " 条链表");
            employLinkedListsArray[i].list();
        }
    }
    //根据id查找雇员
    public void search(int id){
        int emmloyLinkedListNo = hasNun(id);
        if (employLinkedListsArray[emmloyLinkedListNo].search(id) == null){
            System.out.println("所查元素不存在");
        }else{
            System.out.println("所查元素为:" + employLinkedListsArray[emmloyLinkedListNo].search(id) );
        }
    }
    //删除对应的元素
    public void delete(int id){
        int emmloyLinkedListNo = hasNun(id);
        employLinkedListsArray[emmloyLinkedListNo].delete(id);
    }
}

分析与总结:

  1. 虽然链表有相关的增删改除方法,但是只有hashTab能够操作数据,所以HashTab要有能够对数据经进行增删该处的方法
  2. 就算是没有返回数据类型的参数,也可以return来结束当前的方法,美有必要非得else到方法的末尾,才能结束方法。如下面的两种方法:
    用return返回结束程序
public void list(){
        //遍历元素,看看是否为空
        if (isEmpty()){
            System.out.println("链表为空");
            return;
        }
        Employ curBoy = head;
        while (true) {
            System.out.print("id为:" + curBoy.id + "name为:" + curBoy.name + ">>>");
            if (curBoy.next == null) {
                break;
            }
            curBoy = curBoy.next;
        }
        System.out.println();

    }

用else嵌套,运行到程序的尽头

public void list() {
        //遍历元素,看看是否为空
        if (isEmpty()) {
            System.out.println("链表为空");
            return;
        } else {
            Employ curBoy = head;
            while (true) {
                System.out.print("id为:" + curBoy.id + "name为:" + curBoy.name + ">>>");
                if (curBoy.next == null) {
                    break;
                }
                curBoy = curBoy.next;
            }
            System.out.println();
        }
    }
发布了36 篇原创文章 · 获赞 3 · 访问量 1775

猜你喜欢

转载自blog.csdn.net/Blackoutdragon/article/details/104017077
今日推荐