随笔都是学习笔记
随笔仅供参考,为避免笔记中可能出现的错误误导他人,请勿转载。
posts - 398,comments - 0,views - 13万

设计思路:

宠物商店需要一个链表(单向链表随笔可查)来进行宠物信息的存储,一个商店对应多个宠物,多数量的宠物应该具有同一标准,所以需要一个IPet接口来定义宠物标准,然后宠物类为IPet接口的实现类。

链表接口:

复制代码
package Demo_1_29_宠物商店设计;
// 通过接口设置标准
public interface ILink <E> {    // 设置泛型避免安全隐患
    public void add(E e);   // 增加数据
    public int size();  // 获取数据的个数
    public boolean isEmpty();   // 判断集合是否为空
    public Object[] toArray();  // 将集合元素以数组的形式返回保存
    public E get(int index);    // 根据索引获取数据
    public void set(int index, E data); // 修改指定索引数据
    public boolean contains(E data);    // 判断数据是否存在
    public void remove(E e);     // 删除指定节点
    public void clean();    // 清空链表
}
复制代码

 

链表实现类:

复制代码
package Demo_1_29_宠物商店设计;

/*
* 整个过程中LinkImpl类只是进行root节点的创建和add方法参数的接收并向Node节点发出指令addNode(),真正的节点操作类是LinkImpl类中的Node类
* 而节点的连接其实就是引用的传递,Node类只管进行将后节点的引用传给给前节点的next来记录
* data的值是通过客户端传入到LinkImpl的add()方法,所以Node节点并不关心data的值
* */
public class LinkImpl<E> implements ILink<E> {
    // 内部类的属性是提供给外部类使用,那么就没有必要再加上setter和getter方法了
    private class Node{ //保存节点的数据关系
        private E data; //保存的数据
        private Node next;  // 下一个节点的引用
        public Node(E data){    // 有数据才有意义
            this.data = data;
        }
        // 第一次调用:this = LinkImpl.root;
        // 第二次调用:this = LinkImpl.root.next;
        // 第三次调用:this = LinkImpl.root.next.next;
        public void addNode(Node newNode){  // 保存新的Node数据
            if (this.next == null){ //当前节点(根节点)的下一个节点为空
                // 下面将新节点(下一节点)的引用传给当前节点的next以记录地址
                this.next = newNode;    // 根节点的下一节点为newNode(将新节点与前一节点成功连接)
            }else {
                this.next.addNode(newNode); // 递归调用方法知道找出下一节点为空的节点并保存新节点
            }
        }

        // 第一次调用: this = LinkImpl.root
        // 第二次调用: this = LinkImpl.root.next
        // 第三次调用: this = LinkImpl.root.next.next
        public void toArrayNode(){  //  将数据添加到返回数组中
            LinkImpl.this.returnData [LinkImpl.this.foot ++ ] = this.data;  // 当前data添加到数组中
            if (this.next != null){ //还有下一个数据
                this.next.toArrayNode();    // 这一步是this.next调用的toArrayNode方法,递归进行数据的添加
            }
        }
        public E getNode(int index){
            if (LinkImpl.this.foot ++ == index){    // 定位至指定的索引
                return this.data;   // 返回当前数据
            }else {
                return this.next.getNode(index);    // 递归调用继续向下匹配指定的索引
            }
        }
        public void setNode(int index, E data){
            if (LinkImpl.this.foot ++ == index){    // 定位至指定的索引
                this.data = data;   // 返回当前数据
            }else {
                this.next.setNode(index, data);// 递归调用继续向下匹配指定的索引
            }
        }
        public boolean containsNode(E data){
            if (data.equals(this.data)){    // 想要查询的数据等于当前数据则表示存在
                return true;    // 返回真
            }else {     // 想要查询的数据不等当前数据则表示想要查询的数据不在当前位置
                if (this.next == null){
                    return false;   // 当前位置的下一个数据的地址为空返回false(后面没有数据了)
                }else {
                    return this.next.containsNode(data);    // 继续判断想要查询的数据是否在下一个位置
                }
            }
        }
        public void removeNode(Node previous,E data){
            if (this.data.equals(data)){    // 找到指定位置的节点
                System.out.println("删除了节点数据为:" + data + "、地址为:" + previous.next);
                previous.next = this.next;  // 上一节点与当前节点的下一节点连接,以空出当前节点
            }else {     // 当前节点不是指定节点
                if (this.next != null){     // 如果当前节点的下一个节点不为空
                    this.next.removeNode(this,data);    // 这里传入到下一个节点,this是当前节点(下一节点的上节点),data是指定的节点
                }
            }
        }

    }
    /*--------------- 以下为LinkImpl类中定义的成员 ------------------*/
    private Node root;  // 保存根元素
    private int count;  // 保存数据的个数
    private int foot = 0;   // 操作数组的脚标
    private Object[] returnData;    //返回的数据
    /*--------------- 以下为LinkImpl类中定义的方法 ------------------*/
    @Override
    public void add(E e) {
        if (e == null) {//保存的数据为空
            return;
        }
        // 数据本身不具备关联特性,只有Node类有,那么想实现关联处理,就必须将数据包装在Node类中
        Node newNode = new Node(e); // 创建一个新的节点,传入的数据e通过Node类的构造方法赋值给data
        if (this.root == null){
            this.root = newNode;    // 第一个节点为根节点
        }else{  // 根节点存在
            this.root.addNode(newNode);
        }
        this.count ++;
    }

    @Override
    public int size() {
        return this.count;
    }

    @Override
    public boolean isEmpty() {
//        return this.root == null;
        return this.count == 0; // 两个return效果都是一样的,为空则返回true,否则返回false
    }

    @Override
    public Object[] toArray() {
        if (this.isEmpty()){ // 空集合
            return null;
        }
        this.foot = 0;  // 脚标起始为0
        this.returnData = new Object[this.count];   // 当前数据的个数就是返回数组的长度
        this.root.toArrayNode();    // 利用Node类进行递归获取数据
        return this.returnData;
    }

    @Override
    public E get(int index) {
        if (index >= this.count){   // 索引大于数据的个数
            return null;
        }   //索引数据的获取应该由Node类完成
        this.foot = 0;
        return  this.root.getNode(index);
    }

    @Override
    public void set(int index, E data) {
        if (index >= this.count) {   // 索引大于数据的个数
            return; //结束
        }   //索引数据的修改应该由Node类完成
        this.foot = 0;  // 重置索引下标
        this.root.setNode(index,data);   // 修改数据
    }

    @Override
    public boolean contains(E data) {
        if (data == null){
            return false;   // 想查看的数据为空返回false
        }
        return this.root.containsNode(data);
    }

    @Override
    public void remove(E data) {
        if (this.contains(data)){   // 判断想要删除的节点是否存在
            if (this.root.data.equals(data)){   // 如果想要删除的节点已存在,判断是否为根节点
                System.out.println(data + "-->数据为根节点已经删除!");
                this.root = this.root.next;     // 删除根节点
                // 根节点判断完成,以后应该从下一节点开始判断
            }else {
                this.root.next.removeNode(this.root,data);  // 不是根节点那么就让Node节点进行操作,传入根节点作为节点的上一节点,和指定节点data
            }
            this.count --;
        }
    }

    @Override
    public void clean() {
        this.root = null;   // 根节点重置为空(根节点后指向的地址重置为空),后续所有节点为空
        this.count = 0;     // 个数清零
    }
}
复制代码

 

宠物商店类:

复制代码
package Demo_1_29_宠物商店设计;

public class PetShop {  //宠物商店
    private ILink<IPet> allPets = new LinkImpl<>();
    public void add(IPet pet){   // 宠物上架
        this.allPets.add(pet);  // 集合中保存对象
    }
    public void delete(IPet pet){
        this.allPets.remove(pet);
    }
    public ILink<IPet> search(String keyword){
        ILink<IPet> searchRes = new LinkImpl<IPet>(); // 创建查询链表保存查询结果
        Object[] res = this.allPets.toArray();  // 获取全部数据
        if (res != null){
            for (Object obj: res){
                IPet pet = (IPet) obj;
                if (pet.getName().contains(keyword) || pet.getColor().contains(keyword)){   // contains方法字符匹配,输入的kryword在名字中或颜色中时返回true
                    searchRes.add(pet); // 保存查询结果
                }
            }
        }
        return searchRes;

    }
}
复制代码

 

宠物接口:

package Demo_1_29_宠物商店设计;

public interface IPet {  // 宠物接口,定义宠物标准
    public String getName();    // 获取宠物的名字
    public String getColor();       // 获取宠物的颜色
}

 

宠物类(接口实现类)

复制代码
package Demo_1_29_宠物商店设计;

public class Cat implements IPet{   // 实现宠物标准
    private String name;
    private String Color;

    public Cat() {
    }

    public Cat(String name, String color) {
        this.name = name;
        this.Color = color;
    }

    @Override
    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String getColor() {
        return this.Color;
    }

    public void setColor(String color) {
        this.Color = color;
    }
    public boolean equals(Object o){
        if (o == null){
            return false;
        }
        if (!(o instanceof Dog)){   // 不是猫
            return false;
        }
        if (this == o){
            return true;
        }
        Cat cat = (Cat) o;
        return this.name.equals(cat.name) && this.Color.equals(cat.Color);

    }
    public String toString(){
        return "【宠物猫】" + "|-【名字】:" + this.name + ", 【颜色】:" + this.Color + "。";
    }
}
复制代码

 

复制代码
package Demo_1_29_宠物商店设计;

public class Dog implements IPet{   // 实现宠物标准
    private String name;
    private String Color;

    public Dog() {
    }

    public Dog(String name, String color) {
        this.name = name;
        this.Color = color;
    }

    @Override
    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String getColor() {
        return this.Color;
    }

    public void setColor(String color) {
        this.Color = color;
    }
    public boolean equals(Object o){
        if (o == null){
            return false;
        }
        if (!(o instanceof Dog)){   // 不是猫
            return false;
        }
        if (this == o){
            return true;
        }
        Dog dog = (Dog) o;
        return this.name.equals(dog.name) && this.Color.equals(dog.Color);

    }
    public String toString(){
        return "【宠物狗】:" + "|-【名字】:" + this.name + ", 【颜色】:" + this.Color + "。";
    }
}
复制代码

操作主类(客户端):

复制代码
package Demo_1_29_宠物商店设计;

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        PetShop shop = new PetShop();
        shop.add(new Dog("斑点狗", "黑白色"));
        shop.add(new Dog("小黑狗", "黑色"));
        shop.add(new Cat("加菲猫", "橙黄色"));
        shop.add(new Cat("狸花猫", "狸花色"));
        System.out.printf("请输入查询宠物信息的关键字:");
        String keyWord = sc.next();
        Object[] res = shop.search(keyWord).toArray();
//        System.out.println(Arrays.toString(res));
        for (Object o : res){
            System.out.println(o);
        }
    }
}
复制代码

 

 

posted on   时间完全不够用啊  阅读(104)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示