图书大厦
模拟一个图书大厦图书管理的程序结构,可以在大厦实现某一类图书的上架操作、下架操作、关键字模糊查询的操作
个人笔记,如有不同看法勿喷
本代码来自李兴华课堂,点这
侵删
代码块
- 前期准备:链表结构
interface Link {
public void add(Object data);//添加数据
public int size(); //取得保存元素的个数
public boolean isEmpty(); //判断是否为空
public boolean contains(Object data); //查询数据是否在链表中
public Object get(int index);//根据索引取得数据,索引从0开始
// get(int) 与 contains(Object) 不同:一是数字索引,一是内容
public void set(int index, Object obj); //修改索引处数据,记得表中索引从0开始
public void remove(Object obj); //删除数据
public void clear(); //清空链表
public Object [] toArray();//将链表元素转为对象数组
}
class LinkImpl implements Link {
//凡是与节点有关的操作用Node
//凡是与根节点root有关的操作用Link类
private class Node { //使用私有类
private Object data;
private Node next;
public Node(Object data) { //构造函数
this.data = data;
}
public void addNode(Node newNode) { //节点添加函数
if( this.next == null ) {
this.next = newNode;
} else {
this.next.addNode(newNode);
}
}
//第一次:this = LinkImpl.root;
//第二次:this = LinkImpl.root.next;
public boolean containsNode(Object data) {
if( this.data.equals(data)) {
return true;
} else { //继续向下查找
if( this.next!=null ) { //当前节点之后还有下一个节点
return this.next.containsNode(data);
} else {
return false;
}
}
}
public Object getNode(int index) {
if( LinkImpl.this.foot ++==index ) {
return this.data;
} else {
return this.next.getNode(index);
}
}
public void setNode(int index, Object obj) { //类似getNode()
if( LinkImpl.this.foot ++== index )
this.data = obj;
else {
this.next.setNode(index, obj);
}
}
//第一次:this = LinkImpl.root.next, previous = this.root
//第二次:this = LinkImpl.root.next.next, previous = this.root.next
public void removeNode(Node previous, Object data) {
if( this.data.equals(data) ) { //为当前要删除的数据
previous.next = this.next; //空出当前节点
} else {
this.next.removeNode(this, data);
}
}
public void toArrayNode() {
LinkImpl.this.retData[LinkImpl.this.foot++] = this.data;
if( this.next!=null ) {
this.next.toArrayNode();
}
}
}
/******************************/
private Node root; //根元素
private int foot=0; //操作的索引角标
private int count=0; //链表中节点个数
private Object retData[] = null;
public void add(Object data) { //添加数据进链表
if( data==null ) //现在没有要添加的数据
return;
Node newNode = new Node(data); //创建新的节点
if( this.root==null) {//保留根节点
this.root = newNode;
} else { //交给Node类负责
this.root.addNode(newNode);
}
this.count++; //添加成功后节点数加一
}
public int size() { //链表长度
return this.count;
}
public boolean isEmpty() { //判断链表是否为空
return this.root == null; //判断是否为空标准,也可以判断长度是否为0,但推荐这个。
}
public boolean contains(Object data) { //判断链表中是否包含此数值
if( this.root==null ) {//集合没有元素,返回false
return false;
} else {
return this.root.containsNode(data); //不要忘记是在根节点开始找
}
}
public Object get(int index) { //查找索引处数值
if( this.count<=index ) {
return null;
}
this.foot = 0; //每次查询之前清零
return this.root.getNode(index);
}
public void set(int index, Object obj) {
if( index>= this.count )
return;
this.root.setNode(index, obj);
}
public void remove(Object data) {
if( this.contains(data) ) { //存在删除节点
if( this.root.data.equals(data) ) { //删除节点在根节点
this.root = this.root.next; //第二个元素作为根元素
} else { //不是根元素,根元素已判断完了
this.root.next.removeNode(this.root, data);
}
count--;
}
}
public void clear() { //清空链表
this.root = null;
this.count = 0;
//若只有以上两行,则欠缺一个很好的内存释放问题
System.gc(); //回收内存空间
}
//恒定概念:链表就是动态对象数组,但是想操作链表中的数据,那么最好的做法就是将其转化为对象数组返回。
//所以这个时候就需要针对数据做递归处理
public Object [] toArray() {
if( this.root==null )
return null;
this.retData = new Object [this.count];
this.foot = 0; //索引置为空, 为了后面的赋值
this.root.toArrayNode();
return this.retData; //在这里返回,内部类中的toArrayNode() 就不要返回,类型为void
}
}
- 图书大厦准备
interface Book { //准备图书信息
public String getTitle();
public Double getPrice();
}
class BookShop {
private Link books = new LinkImpl(); //所有的书
public void add(Book book) {
this.books.add(book);
}
public void delete(Book book) {
this.books.remove(book);
}
public Link search(String keyWord) { //一堆书,用动态数组-->链表
Link result = new LinkImpl(); //返回值
Object [] obj = this.books.toArray(); //将所有数据转为Object数组
for(int i=0; i<obj.length; i++ ) {
Book book = (Book)obj[i];
if( book.getTitle().contains(keyWord) ) {
result.add(book);
}
}
return result;
}
}
class ComputerBook implements Book {
private String title;
private double price;
public ComputerBook(String title, double price) {
this.title = title;
this.price = price;
}
@Override
public boolean equals(Object obj) {
if( this==obj) {
return true;
}
if( obj==null ) {
return false;
}
if( !(obj instanceof ComputerBook) ) {
return false;
}
ComputerBook b = (ComputerBook) obj;
if( this.title.equals(b.title) && this.price==b.price ) {
return true;
} else {
return false;
}
}
@Override
public String getTitle() {
// TODO Auto-generated method stub
return this.title;
}
@Override
public Double getPrice() {
// TODO Auto-generated method stub
return this.price;
}
public String toString() {
return "【计算机类图书】 名称:"+this.getTitle()+", 价格:"+ this.getPrice();
}
}
class MathBook implements Book {
private String title;
private double price;
public MathBook(String title, double price) {
this.title = title;
this.price = price;
}
@Override
public boolean equals(Object obj) {
if( this==obj) {
return true;
}
if( obj==null ) {
return false;
}
if( !(obj instanceof MathBook) ) {
return false;
}
MathBook b = (MathBook) obj;
if( this.title.equals(b.title) && this.price==b.price ) {
return true;
}
return false;
}
@Override
public String getTitle() {
// TODO Auto-generated method stub
return this.title;
}
@Override
public Double getPrice() {
// TODO Auto-generated method stub
return this.price;
}
public String toString() {
return "【数学类图书】 名称:"+this.getTitle()+", 价格:"+ this.getPrice();
}
}
public class Demo {
public static void main(String[] args) {
BookShop shop = new BookShop();
shop.add(new ComputerBook("java开发",89.2));
shop.add(new ComputerBook("java数据库编程",29.2));
shop.add(new ComputerBook("java网络编程",83.2));
shop.add(new ComputerBook("java2开发",84.2));
shop.add(new MathBook("java开发的数学思想",89.2));
shop.add(new MathBook("数学开发2",893.2));
shop.add(new MathBook("数学",82.2));
shop.delete(new MathBook("java开发的数学思想",89.2));
Link temp = shop.search("java");
Object obj [] = temp.toArray();
for(int i=0; i<obj.length; i++) {
System.out.println(obj[i]);
}
}
}