通讯录管理系统

news/2024/5/17 16:26:22 标签: java, 开发语言, 数据结构, gitee

作者:狮子也疯狂
专栏:《项目集锦》
坚持做好每一步,幸运之神自然会驾凌在你的身上
在这里插入图片描述

目录

  • 一. 🦁 项目描述
  • 二. 🦁编写目的
  • 三. 🦁技术说明
    • 3.1 业务流程结构图
    • 3.2 数据存储结构
    • 3.3 技术要求及开发环境
  • 四. 🦁项目开发
    • 4.1 创建菜单类
    • 4.2 创建实体类
    • 4.3 创建数据校验类
    • 4.4 创建双向链表
    • 4.5 创建持久层文件处理
    • 4.6 创建正则表达式
    • 4.7 创建用户业务层
  • 五. 🦁总结

一. 🦁 项目描述

该项目是用于日常生活中记录联系人信息的一款智能小工具。实现了对联系人的姓名、年龄、性别、电话号码、住址的添加及修改、查找、删除、排序等功能。该项目是以 Windows 控制台为运行平台,所有的操作都应在控制台上进行。

二. 🦁编写目的

通过该项目将平时所学的内容综合到一起并运用到实际的项目中。并且通过实现自己实现的数据结构来实现存储和持久化处理(老师不给用集合,自己实现一个数据结构来存储)
该项目能够充分的体现出一些简单的业务流程处理,能够使同学们掌握基本的业务流程处理。进一步理解什么是面相对象设计(OOD:Object Oriented Design)。充分理解面向对象设计的精髓。
总的来说,就是要完成作业。

三. 🦁技术说明

3.1 业务流程结构图

在这里插入图片描述

3.2 数据存储结构

id序号
name姓名
age年龄
sex性别
telNum电话号码
address地址

3.3 技术要求及开发环境

  • JDK 版本为 11
  • 键盘输入 Scanner 类
  • 正则表达式 Pattern 类
  • 自编写数据结构LinkedList
  • Windows 10 & idea 2020

四. 🦁项目开发

4.1 创建菜单类

进入每个功能模块,用户都有清晰的功能选择。还有返回上一层,降低了代码的耦合性。

java">public class Menus {
        //主界面
        public void mainMenu(){
            System.out.println("--------------⭐------------");
            System.out.println("**         1 添加记录        **");
            System.out.println("**         2 查找记录        **");
            System.out.println("**         3 修改记录        **");
            System.out.println("**         4 删除记录        **");
            System.out.println("**         5 排序记录        **");
            System.out.println("**         6 退出系统        **");
            System.out.println("--------------⭐------------");
        }
        //添加界面
        public void addMenu(){
            System.out.println("--------------⭐------------");
            System.out.println("**         1 添加新记录     **");
            System.out.println("**         2 查看全记录     **");
            System.out.println("**         3 返回上一级     **");
            System.out.println("--------------⭐------------");
        }
        //查找界面
        public void searchMenu(){
            System.out.println("--------------⭐------------");
            System.out.println("**         1 按姓名查找    **");
            System.out.println("**         2 按年龄查找    **");
            System.out.println("**         3 按性别查找    **");
            System.out.println("**         4 按号码查找    **");
            System.out.println("**         5 按住址查找    **");
            System.out.println("**         6 查看全记录    **");
            System.out.println("**         7 返回上一级    **");
            System.out.println("--------------⭐------------");
        }
        //修改界面
        public void modifyMenu(){
            System.out.println("---------------⭐------------");
            System.out.println("**         1 查看全记录    **");
            System.out.println("**         2 修改指定记    **");
            System.out.println("**         3 返回上一级    **");
            System.out.println("--------------⭐------------");
        }
        //修改子界面
        public void subModifyMenu(){
            System.out.println("--------------⭐------------");
            System.out.println("**         1 修改姓名    **");
            System.out.println("**         2 修改年龄    **");
            System.out.println("**         3 修改性别    **");
            System.out.println("**         4 修改号码    **");
            System.out.println("**         5 修改住址    **");
            System.out.println("**         6 返回上一级   **");
            System.out.println("--------------⭐------------");
        }
        //删除界面
        public void deleteMenu(){
            System.out.println("--------------⭐------------");
            System.out.println("**         1 查看全部记录  **");
            System.out.println("**         2 删除指定记录  **");
            System.out.println("**         3 删除全部记录  **");
            System.out.println("**         4 返回上一级    **");
            System.out.println("--------------⭐------------");
        }
        //排序界面
        public void orderMenu(){
            System.out.println("--------------⭐------------");
            System.out.println("**         1 按姓名排序  **");
            System.out.println("**         2 按年龄排序  **");
            System.out.println("**         3 按性别排序  **");
            System.out.println("**         4 查看全部记录 **");
            System.out.println("**         5 返回上一级  **");
            System.out.println("--------------⭐------------");
        }
}

在这里插入图片描述

4.2 创建实体类

java">import java.io.Serializable;
public class Users implements Serializable {
    private int id;
    private String name;
    private int age;
    private String sex;
    private String telNum;
    private String address;

    public Users() {
    }
    public Users(String name, int age, String sex, String telNum, String address) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.telNum = telNum;
        this.address = address;
    }

    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 int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getTelNum() {
        return telNum;
    }

    public void setTelNum(String telNum) {
        this.telNum = telNum;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "id=" + id +
                "\tname: " + name  +
                " age:  " + age  +
                " sex:  " + sex  +
                " telNum:   " + telNum  +
                " address:  " + address  +"\t\t";
    }
}

4.3 创建数据校验类

数据校验类是为了避免在使用过程,用户输入错误的数据又跳转了,导致系统出错。

java">import java.util.Scanner;
public class Varify {
    Scanner S = new Scanner(System.in);
    /**
     * 校验主菜单
     * @param min
     * @param max
     * @return int
     */
    public int menuVarify(int min,int max){         //菜单选项验证
        String str1 = "\\d";
        while(true){
            System.out.println("最小为"+min+","+"最大为"+max+";"+"请输入您的选择:");
            String input = S.nextLine();
            if(input.matches(str1)){
                int num = Integer.parseInt(input);
                if(num >=min&&num<=max){
                    return num;
                }else{
                    System.out.println("请输入有效数字!!!");
                }
            }else{
                System.out.println("您的输入有误,请重新输入!!!");
            }
        }
    }

    /**
     * 校验名字
     * 汉字或者字母
     * @return name
     */
    public String nameVarity(){
        String str = "[A-Za-z\\u4e00-\\u9fa5]{1,10}";
        while (true){
            System.out.println("请输入您的名字(中文/英文):");
            String name = S.nextLine();
            if(name.matches(str)){
                return name;
            }else{
                System.out.println("您的输入有误,请重新输入!");
            }
        }
    }

    /**
     *
     * @return
     */
    public int ageVarity(){
        String str = "\\d{0,125}";
        while(true){
            System.out.println("请输入您的年龄:(0-125)");
            String age = S.nextLine();
            if(age.matches(str)){
                return Integer.parseInt(age);
            }else{
                System.out.println("输入有误,请重新输入!");
            }
        }
    }
    public String sexVarity(){
        String str = "[男|女]{1}";
        while(true){
            System.out.println("请输入您的性别:(男/女)");
            String sex = S.nextLine();
            if(sex.matches(str)){
                return sex;
            }else{
                System.out.println("输入有误,请重新输入!");
            }
        }
    }
    public String tellNumVarity(){
        String str = "(\\d{3,4}-\\d{7,8})|([1]{1}\\d{10})";
        while(true){
            System.out.println("请输入电话号码或者座机号码:");
            String inputNum = S.nextLine();
            if(inputNum .matches(str)){
                return inputNum;
            }else{
                System.out.println("您输入的电话号码有误,请重新输入:");
            }
        }
    }
    public String addressVarity(){
        String str = "[a-zA-Z\\u4e00-\\u9fa5]{1,50}";
        while(true){
            System.out.println("请输入地址:字母或者汉字");
            String inputName = S.nextLine();
            if(inputName.matches(str)){
                return inputName;
            }else{
                System.out.println("您输入的地址有误,请重新输入:");
            }
        }
    }
}

4.4 创建双向链表

这个是模仿LinkedList的双向链表,里面有基本添加,删除,清空链表功能。

java">import java.io.Serializable;

public class DoubleLinkedList<E> implements ListInterface<E>, Serializable {
    private Node<E> headNode;       //记录头结点
    private Node<E> tailNode;       //记录尾结点
    private int size;               //记录结点数
    public int getSize() {
        return size;
    }

    /**
     * 定义结点类
     * @param <E>
     */
    class Node<E> implements Serializable{
         Node prevNode;             //前
         E element;                 //记录元素
         Node next;                 //后

        public Node(Node prevNode, E element, Node next) {
            this.prevNode = prevNode;
            this.element = element;
            this.next = next;
        }

        public Node(E element) {
            this.element = element;
        }
    }

    private void addNode(E element){
        Node t = this.tailNode;
        Node node = new Node(t,element,null);
        this.tailNode = node;
        if(t == null){
            this.headNode = node;
        }else{
            t.next = node;
        }
        this.size++;
    }

    /**
     * 添加元素
     * @param element
     */
    @Override
    public void add(E element) {
        this.addNode(element);
    }
    private Node getNode(int index){
        if(index <= (this.size>>1)){
            Node node = this.headNode;
            for(int i = 0;i<index;i++){
                node = node.next;
            }
            return node;
        }
        else{
           Node node = this.tailNode;
            for(int i = this.size-1;i>index;i--){
                node = node.prevNode;
            }
            return node;
        }
    }

    /**
     * 在指定位置添加元素
     * @param index
     * @param element
     */
    @Override
    public  void add(int index,E element){
        if(index < 0||index >=this.size){
            throw new IndexOutOfBoundsException("下标不合法:"+index);
        }
        Node<E> node = new Node(element);
        if(index == 0){
            node.next = this.headNode;
            this.headNode.prevNode = node;
            this.headNode = node;
        }else if(index+1 == this.size){
            this.tailNode.next = node;
            node.prevNode = tailNode;
            this.tailNode = node;
        }else{
            Node<E> temp = this.getNode(index-1);
            node.next = temp.next;
            temp.prevNode = node;
            temp.next = node;
            node.prevNode = temp;
        }
        this.size++;
    }

    /**
     * 根据下标添加元素
     * @param index
     * @return
     */
    @Override
    public E get(int index) {
        if(index < 0||index >=this.size){
            throw new IndexOutOfBoundsException("下标不合法:"+index);
        }
      Node<E> node = this.getNode(index);
        return node.element;
    }

    @Override               //删除元素
    public boolean remove(int index) {
        if(index <0||index >=this.size){
            throw new IndexOutOfBoundsException("下标不合法:"+index);
        }
        Node<E> node = this.getNode(index);
        if(node.prevNode == null){
            this.headNode = node.next;
        }else{
            node.prevNode.next = node.next;
        }

        if(node.next == null){
            this.tailNode = node.prevNode;
        } else{
            node.next.prevNode = node.prevNode;

        }
        node.prevNode = null;
        this.size--;
        return true;
    }
    @Override               //清空所有元素
    public boolean removeAll(){
        this.headNode = null;
        this.tailNode = null;
        this.size = 0;
        return true;
    }
}

4.5 创建持久层文件处理

创建一个IoUtil包,封装好了读取文件方法,和将数据写入文件的方法,专门进行文件的读取和写入,简化了在使用过程中,创建输入输出流的繁琐步骤,加快了生产效率。

java">import java.io.*;

/**
 * 文件读取
 */
public class IoUtil {
    /**
     * 读取文件
     * @param fileName
     * @return
     * @throws IOException
     */
  	public static  Object readFile(String fileName) throws IOException, ClassNotFoundException {
            FileInputStream fileInputStream = new FileInputStream(fileName);
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            return objectInputStream.readObject();
        }
  	public static void writeFile(Object obj,String fileName) throws IOException {
      		ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(fileName));
      		objectOutputStream.writeObject(obj);
  }
}

4.6 创建正则表达式

tips:
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。使用特殊语法来表示字符类、数量限定符和位置关系,然后用这些特殊语法和普通字符一起表示一个模式。

这里的校验类有很多种,分别有主菜单的校验,名字的校验,年龄输入的校验,电话号码是否输入正确的校验,还有地址的校验。实现详情请看以下代码:

java">import java.util.Scanner;
public class Varify {
    Scanner S = new Scanner(System.in);
    /**
     * 校验主菜单
     * @param min
     * @param max
     * @return int
     */
    public int menuVarify(int min,int max){         //菜单选项验证
        String str1 = "\\d";
        while(true){
            System.out.println("最小为"+min+","+"最大为"+max+";"+"请输入您的选择:");
            String input = S.nextLine();
            if(input.matches(str1)){
                int num = Integer.parseInt(input);
                if(num >=min&&num<=max){
                    return num;
                }else{
                    System.out.println("请输入有效数字!!!");
                }
            }else{
                System.out.println("您的输入有误,请重新输入!!!");
            }
        }
    }

    /**
     * 校验名字
     * 汉字或者字母
     * @return name
     */
    public String nameVarity(){
        String str = "[A-Za-z\\u4e00-\\u9fa5]{1,10}";
        while (true){
            System.out.println("请输入您的名字(中文/英文):");
            String name = S.nextLine();
            if(name.matches(str)){
                return name;
            }else{
                System.out.println("您的输入有误,请重新输入!");
            }
        }
    }

    /**
     *
     * @return
     */
    public int ageVarity(){
        String str = "\\d{0,125}";
        while(true){
            System.out.println("请输入您的年龄:(0-125)");
            String age = S.nextLine();
            if(age.matches(str)){
                return Integer.parseInt(age);
            }else{
                System.out.println("输入有误,请重新输入!");
            }
        }
    }
    public String sexVarity(){
        String str = "[男|女]{1}";
        while(true){
            System.out.println("请输入您的性别:(男/女)");
            String sex = S.nextLine();
            if(sex.matches(str)){
                return sex;
            }else{
                System.out.println("输入有误,请重新输入!");
            }
        }
    }
    public String tellNumVarity(){
        String str = "(\\d{3,4}-\\d{7,8})|([1]{1}\\d{10})";
        while(true){
            System.out.println("请输入电话号码或者座机号码:");
            String inputNum = S.nextLine();
            if(inputNum .matches(str)){
                return inputNum;
            }else{
                System.out.println("您输入的电话号码有误,请重新输入:");
            }
        }
    }
    public String addressVarity(){
        String str = "[a-zA-Z\\u4e00-\\u9fa5]{1,50}";
        while(true){
            System.out.println("请输入地址:字母或者汉字");
            String inputName = S.nextLine();
            if(inputName.matches(str)){
                return inputName;
            }else{
                System.out.println("您输入的地址有误,请重新输入:");
            }
        }
    }
}

4.7 创建用户业务层

功能太多,但是较为简单,就不一一阐述。

五. 🦁总结

一个跟数据结构挂钩的期末实验,功能实现并不复杂,接近crud,但是构造整体框架很复杂,花费了很多精力去打磨。唯一一个难点就是双向链表的编写;还有就是正则表达式的使用不够熟练,查询了很多资料,才知道如何去使用。给大家介绍了一个很简单的Java小项目入门,希望大家喜欢。
项目已经开源到git,感兴趣的小伙伴点击:下载


http://www.niftyadmin.cn/n/32173.html

相关文章

vite兼容chrome48的方法

chrome48不支持async await语法&#xff0c;但有些桌面客户端的内嵌浏览器就是chrome48,如下操作即可兼容 当前环境&#xff1a;2023-2-3使用npm create vitelatest创建 开始兼容操作 安装vite推荐的 vitejs/plugin-legacy 文档官网 https://github.com/vitejs/vite/tree/m…

Python---方法(普通方法,类方法,静态方法)

专栏&#xff1a;python 个人主页&#xff1a;HaiFan. 专栏简介&#xff1a;Python基础已经更新完&#xff0c;接下来是Python面向对象的知识点。 方法前言普通方法类方法静态方法总结前言 方法是什么&#xff1f; 一个类&#xff0c;它有特征&#xff0c;也有动作&#xff0…

分布式(三)

三、API 网关详解 1. 网关及作用 主要功能&#xff1a;请求过滤 网关可以为我们提供请求转发、安全认证&#xff08;身份/权限认证&#xff09;、流量控制、负载均衡、降级熔断、日志、监控等功能。 2. 常见的网关系统 2.1 Netflix Zuul &#xff08;1&#xff09;Zuul 是…

【3】KVM虚拟化存储 | 虚拟机磁盘挂载

目录 【概念】 一、存储池管理 1.创建基于文件夹的存储池&#xff08;目录) 2.定义存储池与其目录 3.创建已定义的存储池 4.激活并自动启动已定义的存储池 5.在存储池中创建虚拟机存储卷 6.存储池相关管理命令 二、生产环境存储池使用 三、磁盘格式 1.磁盘镜像文件…

西湖论剑2022部分misc

文章目录签到题喵take_the_zip_easymp3机你太美签到题喵 把文件尾的16进制复制出来&#xff0c;再转换字符串 私信后台即可获得flag take_the_zip_easy 明文攻击 echo -n “dasflow.pcapng” > 1.txt time ./bkcrack -C zipeasy.zip -c dasflow.zip -p 1.txt -o 30 -x 0…

windows下通过uiAutomation技术获取ui元素

最近接个需求&#xff0c;要求获取 windows 下 ui 元素&#xff0c;经一番搜索后了解到可通过工具 UISpy.exe 或 inspect.exe 来进行查看。以软件 davinci resolve 为例&#xff1a; 右侧即 UISpy 工具&#xff0c;根据内容可以看出已捕获到 davinci 界面的各属性及对应值。而 …

java对象的比较

上一章中关于PriorityQueue的使用要注意&#xff1a; 1. PriorityQueue中放置的元素必须要能够比较大小&#xff0c;不能插入无法比较大小的对象&#xff0c;否则会抛出 ClassCastException异常 2. 不能插入null对象&#xff0c;否则会抛出NullPointerException 3. 没有容量限制…

看这个就够了——ubuntu系统中的cuda cudnn cudatookit及pytorch使用

一.基本概念1.1 nvidia独立显卡独立显卡是指以独立板卡形式存在&#xff0c;可在具备显卡接口的主板上自由插拔的显卡。独立显卡具备单独的显存&#xff0c;不占用系统内存&#xff0c;而且技术上领先于集成显卡&#xff0c;能够提供更好的显示效果和运行性能。显卡作为电脑主机…