链表实战之宠物商店 | 带你学《Java面向对象编程》之九十五

简介: 本节结合在宠物商店出售各种宠物的实际情景,制定宠物、宠物店的标准并进行实现,结合链表实现对商店内宠物的动态数据操作。

上一篇:链表数据“暗杀记” | 带你学《Java面向对象编程》之九十四
【本节目标】
通过阅读本节内容,你将通过编码实现宠物商店的情景,进一步复习接口的相关知识,进一步掌握链表的结构与功能实现以及使用链表解决实际问题的能力。

综合实战:宠物商店

宠物商店:
现在假设一个宠物商店,里面可以出售各种宠物,要求可以实现宠物的上架,下架处理,也可以根据关键字查询宠物的信息。

image.png
图一 宠物设计实现

步骤:
1、应该定义出宠物的标准
2、定义宠物商店
3、根据宠物标准定义宠物信息(定义宠物猫、宠物狗)
4、实现宠物商店的操作

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() ;    //清空集合
}
class LinkImpl<E> implements ILink<E> {
      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) {   //当前节点的下一个节点为null
                           this.next = 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 ;
                     if (this.next != null) {     //还有下一个数据
                          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 ;   //找不到
                           }else {
                                  return this.next.containsNode(data) ;   //向后继续判断 
                           }
                     }
               }
               public void removeNode(Node<E> previous,E date) {
                      if (this.date.equals(date)) {
                           previous.next = this.next ;
                      }else {
                          if (this.next!=null) {
                                this.next.removeNode(this,date) ;
                          }
                      }
               }
               public void removeNode (Node previous,E data) {
                      if (this.data.equals(data)) {
                            previous.next = this.next ;    //空出当前节点
                      }else {
                            if (this.next != null) {       //有后续节点
                                 this.next.removeNode(this, data) ;    //向后继续删除
                           }
                     }
               }
      }
      //------------以下为Link类中定义的成员-----------------
      private Node root ;       //保存根元素
      private int count ;     //保存数据的个数
      private int foot ;     //描述的是操作数组的脚标
      private Object[] returnData ;   //返回的数据保存
      //------------以下为Link类中定义的方法-----------------
      public void add(E e){
         if(e == null){
             return ;
         }
        //数据本身是不具有关联特性的,只有Node类有,要想关联处理就必须将数据包装在Node类中
         Node newNode = new Node(e);    //创建一个新的节点
         if (this.root == null){            //现在没有根节点
            this.root = newNode;       //第一个节点作为根节点
         }else{                          //根节点存在
           this.root.addNode(newNode);       //将新节点保存在合适的位置
         }   
         this.count++ ;  
     }
     public int size() {
            return this.count ;
     }
     public boolean isEmpty() {
             //return this.root == null ;
             return this.count == 0 ;
     }
     public Object[] toArray() {
            if (this.isEmpty()) {           //空集合
                return null ;      //现在没有数据
            }
            this.foot = 0 ;  //脚标清零
            this.returnData = new Object[this.count] ;   //根据已有的长度开辟数组
            this.root.toArrayNode() ; //利用Node类进行递归数据获取
            return this.returnData ;
     }
     public E get(int index) {
           if (index >= this.count) {    //索引应该在指定的范围之内
                return null ;
           }    //索引数据的获取应该由Node类完成
           this.foot = 0 ;   //重置索引的下标
           return this.root.getNode(index) ;
     }
     public void set(int index,E data) {
             if (index >= this.count) {    //索引应该在指定的范围之内
                return  ;     //方法结束
           }    //索引数据的获取应该由Node类完成
           this.foot = 0 ;   //重置索引的下标
           this.root.setNode(index,data) ;  //修改数据
     }  
     public boolean contains(E data) {
            if (data == null) {
                 return false ;     //没有数据
            }
            return this.root.containsNode(data) ;    //交给Node类判断
     }
     public void remove(E data) {
            if (this.contains(data)) {     //判断数据是否存在
                  if (this.root.data.equals(data)) {       //根节点为要删除节点
                      this.root = this.root.next ;    //根的下一个节点  
                  }else {         //交由Node类进行删除
                       this.root.next.removeNode(this.root , data) ;
                  }
                  this.count -- ;
            }
     }
     public void clean() {
           this.root = null ;  //后续的所有节点都没了
           this.count = 0 ;   //个数清零
     }
}
interface Pet{            //定义宠物标准
    public String getName();       //获得名字
    public String getColor();       //获得颜色
}
class Petshop{                 //宠物商店
    private ILink<Pet> allPets = new LinkImpl<Pet>();  //保存多个宠物
    public void add(Pet pet) {      //追加宠物,商品上架
        this.allPets.add(pet);      //集合中保存对象
    }
    public void delete(Pet pet) {
        this.allPets.remove(pet);
    }
    public ILink<Pet> search(String keyword){
        ILink<Pet> searchresult = new LinkImpl<Pet>(); //保存查询结果
        Object result[] = this.allPets.toArray();      //获取全部数据
        if(result !=null ) {
            for(Object obj:result) {
                Pet pet = (Pet)obj;
                if(pet.getName().contains(keyword)||
                    pet.getColor().contains(keyword)) {
                    searchresult.add(pet); //保存查询结果
                }
            }
        }
        return searchresult;
    }
}
class Cat implements Pet{ //实现宠物标准
    private String name;
    private String color;
    public Cat(String name,String color) {
        this.name = name;
        this.color = color;
    }
    public String getName() {
        return this.name;
    }
    public String getColor() {
        return this.color;
}
public boolean equals(Object obj) {
    if(obj == null) {
        return false ;
}
if (!(obj instanceof Cat)) {
    return false ;
}
if (this == obj) {
    return true ;
}
Cat cat = (Cat) obj ;
return this.name.equals(cat.name) && this.color.equals(cat.color) ;
}
    public String toString() {
        return "【宠物猫】名字:"+this.name+"、颜色:"+this.color;
    }
}
class Dog implements Pet{
    private String name;
    private String color;
    public Dog(String name,String color) {
        this.name = name;
        this.color = color;
    }
    public String getName() {
        return this.name;
    }
    public String getColor() {
        return this.color;
}
public boolean equals(Object obj) {
    if(obj == null) {
        return false ;
}
if (!(obj instanceof Dog)) {
    return false ;
}
if (this == obj) {
    return true ;
}
Dog dog = (Dog) obj ;
return this.name.equals(dog.name) && this.color.equals(dog.color) ;
}

    public String toString() {
        return "【宠物狗】名字:"+this.name+"、颜色:"+this.color;
    }
}
public class ListCon{
    public static void main(String args[]) {
        Petshop shop = new Petshop();  //开店
        shop.add(new Dog("黄斑狗","绿色"));
        shop.add(new Cat("小强猫","深绿色"));
        shop.add(new Dog ("黄猫","深色"));
        shop.add(new Dog ("黄狗","黄色"));
        shop.add(new Dog ("斑点狗","灰色"));
        Object result[] = shop.search("黄").toArray();
        for(Object obj : result) {
            System.out.println(obj);
        }
    }
}

image.png
图二 执行结果图

所有的程序开发都是以接口为标准的,这样在进行后期程序处理的时候就可以非常灵活,只要符合标准的对象都可以保存。

想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学

下一篇:链表实战之超市购物车 | 带你学《Java面向对象编程》之九十六
更多Java面向对象编程文章查看此处

相关文章
|
14小时前
|
存储 Java 数据格式
Java实战:轻松掌握文件重命名与路径提取技巧
Java实战:轻松掌握文件重命名与路径提取技巧
5 0
|
2天前
|
设计模式 算法 安全
Java多线程编程实战:从入门到精通
【4月更文挑战第30天】本文介绍了Java多线程编程的基础,包括线程概念、创建线程(继承`Thread`或实现`Runnable`)、线程生命周期。还讨论了线程同步与锁(同步代码块、`ReentrantLock`)、线程间通信(等待/通知、并发集合)以及实战技巧,如使用线程池、线程安全设计模式和避免死锁。性能优化方面,建议减少锁粒度和使用非阻塞算法。理解这些概念和技术对于编写高效、可靠的多线程程序至关重要。
|
3天前
|
XML Java 测试技术
Java异常处理神器:Guava Throwables类概念与实战
【4月更文挑战第29天】在Java开发中,异常处理是保证程序稳定性和可靠性的关键。Google的Guava库提供了一个强大的工具类Throwables,用于简化和增强异常处理。本篇博客将探讨Throwables类的核心功能及其在实战中的应用。
12 2
|
3天前
|
安全 Java 测试技术
利用Java反射机制提高Spring Boot的代码质量:概念与实战
【4月更文挑战第29天】Java反射机制提供了一种强大的方法来在运行时检查或修改类和对象的行为。在Spring Boot应用中,合理利用反射可以提高代码的灵活性和可维护性。本篇博客将探讨Java反射的核心概念,并展示如何通过反射提高Spring Boot项目的代码质量。
16 0
|
3天前
|
存储 Java 大数据
JAVA:编程的艺术与实战解析
JAVA:编程的艺术与实战解析
13 2
|
5天前
|
监控 Java API
Java 模块化设计:概念与实战应用
【4月更文挑战第27天】模块化设计是现代软件开发的关键,它帮助开发者构建可管理、可维护的大型系统。Java 平台的模块化支持始于 Java 9,引入了一种全新的模块系统。
13 3
|
5天前
|
存储 SQL 安全
Java 安全性编程:基本概念与实战指南
【4月更文挑战第27天】在当今的软件开发领域,安全性编程是一个至关重要的方面。Java,作为广泛使用的编程语言之一,提供了多种机制来保护应用免受常见的安全威胁。本博客将探讨 Java 安全性编程的基本概念,并通过实际示例来展示如何实现这些安全措施。
12 3
【Java数据结构】经典链表OJ题——超详细做题笔记及心得(二)
【Java数据结构】经典链表OJ题——超详细做题笔记及心得(每行代码都有注释嗷)
【Java数据结构】经典链表OJ题——超详细做题笔记及心得(二)
【Java数据结构】经典链表OJ题——超详细做题笔记及心得(一)
【Java数据结构】经典链表OJ题——超详细做题笔记及心得(每行代码都有注释嗷)
【Java数据结构】经典链表OJ题——超详细做题笔记及心得(一)
|
1天前
|
存储 安全 Java
深入理解Java并发编程:线程安全与性能优化
【5月更文挑战第1天】本文将深入探讨Java并发编程的核心概念,包括线程安全和性能优化。我们将详细分析线程安全问题的根源,以及如何通过合理的设计和编码实践来避免常见的并发问题。同时,我们还将探讨如何在保证线程安全的前提下,提高程序的并发性能,包括使用高效的同步机制、减少锁的竞争以及利用现代硬件的并行能力等技术手段。