//宠物商店模型
//链表类,外部能看见的只有这一个
//之所以定义在内部,主要是让其为Link类服务
class Link {
private class Node {//定义的节点类
private String data; //保存数据
private Node next; //引用关系
public Node(String data){
this.data=data;
}
//第一次调用(Link):this=Link.root
//第二次调用(Node):this=Link.root.next
public boolean containsNode(String data){
if(data.equals(this.data)){//当前节点没有数据为要查询的数据
return true; //后面不再查询了
}else{ //当前节点数据不满足查询要求
if(this.next!=null){ //有后续节点
return this.next.containsNode(data);
}else{ //没有后续节点
return false; //没得查了
}
}
}
public String getNode(int index){
//使用当前的foot内容与要查询的索引进行比较
//随后将foot的内容自增,目的是为了下一次查询方便
if (Link.this.foot++==index) { //为要查询的索引
return this.data; //返回当前节点数据
}else{ //现在应该继续向后查询
return this.next.getNode(index);
}
}
public void setNode(int index,String data){
if (Link.this.foot++==index){
this.data=data; //进行内容的修改
}else{
this.next.setNode(index,data);
}
}
//第一次调用(Link),previous=Link.root、this=Link.root.next
//第二次调用(Node),previous=Link.root.next、this=Link.root.next.next
//要传递上一个节点以及要删除的数据
public void removeNode(Node previous,String data){
if (data.equals(this.data)) { //当前节点为要删除节点
previous.next=this.next; //空出当前节点
}else{ //一个向后继续查询
this.next.removeNode(this.data);
}
}
//第一次调用(Link),this=Link.root;
//第二次调用(Node),this=Link.root.next;
public void toArrayNode(){
Link.this.retArray[Link.this.foot++]=this.data;
if (this.next!=null) { //有后续元素
this.next.toArrayNode();
}
}
}
//------------以上为内部类------------------
private Node root; //需要根节点
private int count=0; //保存元素的个数
private int foot=0;
private String [] retArray; //返回的数组
public void add(String data){ //假设不允许有null
Node newNode=new Node(data); //保存的数据
if (this.root==null) {//当前没有根节点
this.root=newNode; //保存根节点
}else{ //根节点存在,其他节点交给Node
this.next.addNode(newNode);
}
this.count++; //每一次保存完成后数据量加1.
}
public int size(){ //取得保存的数据量
return this.count;
}
public boolean isEmpty(){
return this.count==0;
}
public String get(int index){
if (index >this.count) { //超过了查询范围
return null; //没有数据
}
this.foot=0; //表示从前向后查询
return this.root.getNode(index); //查询过程交给Node类
}
public boolean contains(String data){
//现在没有要查询的数据,根节点也不保存数据
if(data==null ||this.root==null){
return false; //没有查询结果
}
return this.root.containsNode(data);
}
public void set(int index,String data){
if (index>this.count){
return; //结束方法调用
}
this.foot=0; //重新设置foot属性的内容,作为索引出现
this.root.setNode(index,data);//交给Node类设置数据内容
}
public String[] toArray(){
if (this.root==null){
return null;
}
this.foot=0; //需要脚标控制
this.retArray=new String[this.count]; //根据保存内容开辟数组
this.root.toArrayNode(); //交给Node类处理
return this.retArray;
}
public void remove((String data){
if (this.contains(data)){//判断数据是否存在
//要删除数据是否是根节点数据
//root是Node类对象,此处直接访问了内部类的私有操作
if (data.equals(this.root.data)) { //为要删除节点
this.root=this.root.next; //空出当前根节点
}else{ //不是根元素
//此时根元素已经判断过了,从第二个元素开始判断
this.root.next.removeNode(this.root,data);
}
this.count--; //个数要减少
}
}
interface Pet{ //定义一个宠物的标准
public String getName(); //得到宠物的名字
public int getAge(); //得到宠物的年龄
}
class PetShop{ //一个宠物商店要保存有多个宠物
private Link pets=new Link();
public void add(Pet pet){ //上架
this.pets.add(pet); //向集合里面保存数据
}
public void delete(Pet pet){ //下架
this.pets.remove(pet);
}
//模糊查询一定是返回多个内容,不知道多少个,返回Link即可
public Link search(String keyWord){
Link result=new Link(); //保存结果
//将集合变为对象数组的形式返回,因为集合保存的是Object
//但是真正要查询的数据在Pet接口对象的getName()方法的返回值。
Object obj[]=this.pets.toArray();
for (int x=0;x<obj.length ;x++ ){
Pet p=(Pet) obj[x];
if (p.getName().contains(keyWork)){ //查询到了
result.add(p);//保存满足条件的结果
}
return result;
}
}
class Cat implements Pet{
private String name;
private int age;
public Cat(String name,int age){
this.name=name;
this.age=age;
}
public boolean equals(Object obj){
if (this==obj) {
return true;
}
if (obj==null){
return false;
}
if (!(obj instanceof Cat)){
return false;
}
Cat c=(Cat) obj;
if (this.name.equals(c.name)&&this.age==c.age){
return true;
}
return false;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public String toString (){
return "猫的名字:"+this.name+",猫的年龄:"+this.age;
}
}
class Dog implements Pet{
private String name;
private int age;
public Dog(String name,int age){
this.name=name;
this.age=age;
}
public boolean equals(Object obj){
if (this==obj) {
return true;
}
if (obj==null){
return false;
}
if (!(obj instanceof Dog)){
return false;
}
Dog c=(Dog) obj;
if (this.name.equals(c.name)&&this.age==c.age){
return true;
}
return false;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public String toString (){
return "狗的名字:"+this.name+",狗的年龄:"+this.age;
}
}
public class PetShop{
public static void main(String args[]){
PetShop shop=new PetShop();
shop.add(new Cat("王猫",20));
shop.add(new Cat("黑猫",20));
shop.add(new Cat("白猫",20));
shop.add(new Dog("黑狗",20));
shop.add(new Dog("黄狗",20));
shop.add(new Dog("土狗",20));
shop.delete(new Dog("黑狗",20));
Link all=shop.search("黄");
Object obj[]=all.toArray();
for (int x=0;x<obj.length ;x++ ){
System.out.println(obj[x]);
}
}
}
本程序主要的功能就是利用链表操作宠物信息, 在增加、删除宠物信息时, 接收的参数都是Pet接口类型, 这样只要是此接口的子类对象都可以进行链表操作。而在进行模糊信息查询时, 由于满足条件的宠物名称会存在多个, 所以方法返回类型为Link()此时一个程序的基本结构已经搭建完成, 但是还需要有具体的宠物信息, 而由于考虑到宠物下架(删除)问题, 所以在每个子类中都必须覆写equals()方法。
本程序实现了宠物商店具体的上架、下架、关键字查询的操作, 通过查询结果可以发现,由于摊序是面向接口的编程,所以返回的结果中就有可能同时包含Cat类与Dog类对象。