01 29Java中级之链表的定义及使用

1 链表实现简介

链表的本质是一个动态的对象数组,它可以实现若干个对象的存储。

在实际的开发之中对象数组是一项非常实用的技术,并且利用其可以描述出“多”方的概念,例如:一个人有多本书,那么在人的类里面一定提供有一个对象数组保存书的信息,但是传统的对象数组依赖于数组的概念,所以数组里面最大的缺点在于“长度是固定的”,正是因为如此所以在实际的开发过程之中,传统的数组应用是非常有限的(数组的接收以及循环处理),如果要想进行灵活的数据保存,那么就必须自己来实现结构。

传统对象数组的开发操作依赖于脚标(索引)控制,如果要想实现内容的动态维护,那么难度太高了,而且复杂度攀升,所以现在就可以发现,对于一成不变的数据可以使用对象数组来实现,但是对于可能随时变化的数据就必须实现一个可以动态扩充的对象数组。

所谓的链表的实质是利用引用的逻辑关系来实现类似于数组的数据处理操作,以一种保存“多”方数据的形式实现数组类似的功能。

要想实现链表处理,那么需要有一个公共的结构,这个结构可以实现数据的保存以及下一个连接的指向。为了描述这样的逻辑,可以把每一个存储理解为一个节点,所以此时应该准备出一个节点类,但是这个节点类里面可以保存各种数据类型的数据。

虽然已经知道要通过node节点来进行数据的保存,但是还需要牵扯到节点的引用处理关系,那么这个引用处理关系是由使用者控制吗?这样肯定不可能,所以应该有一个专门的类来进行节点引用关系的配置。
范例:直接操作Node很麻烦

class Node<E>{
	private E data;
	private Node next;

	public Node(){}

	public Node(E data){
		this.data = data;
		this.next = null;
	}

	public void setData(E data){
		this.data = data;
	}

	public void setNext(Node next){
		this.next = next;
	}

	public E getData(){
		return this.data;
	}

	public Node getNext(){
		return this.next;
	}
}

public class LinkDemo 
{
	public static void main(String[] args) {
		Node<String> linka = new Node<String>();
		Node<String> linkb = new Node<String>();
		Node<String> linkc = new Node<String>();
		linka.setData("hello");
		linkb.setData("world");
		linkc.setData("hhy");
		linka.setNext(linkb);
		linkb.setNext(linkc);
		Node<String> temp=linka;
		while(temp != null){
			System.out.println(temp.getData());
			temp = temp.getNext();
		}
	}
}


所以应该有个专门的类来进行节点关系的配置,所以应该对Node类进行包装处理。

2 数据保存:public void add(E e)

通过前面分析可以发现在进行链表操作过程之中为了避免转型的异常应该使用泛型,同时也应该设计一个链表的标准接口,同时具体实现该接口的时候还应该通过Node类做出节点的关系描述。

范例:基本结构

interface ILink<E>{
	public abstract void add(E e);
}

class LinkImpl<E> implements ILink<E>{
	private class Node{
		private E data;
		private Node next;
	}
}

在现在定义的结构中并没有setter和getter方法,因为内部类中的私有属性页方便外部类直接访问。
范例:实现数据增加

interface ILink<E>{
	public abstract void add(E e);
}

class LinkImpl<E> implements ILink<E>{
	private class Node{
		private E data;
		private Node next;

		public Node(){}

		public Node(E data){
			this.data = data;
			this.next = null;
		}

		public void addNode(Node newNode){
			if(this.next == null){
				this.next = newNode;
			}else{
				this.next.addNode(newNode);
			}
		}
	}

	private Node root = null;

	public void add(E e){
		if(e == null){
			return ;
		}else{
			Node newNode = new Node(e);
			if( root == null ){
				root = newNode;
			}else{
				root.addNode(newNode);
			}
		}
	}
}

Link类只是负责数据的操作与根节点的处理,而所有后续节点的处理全部都由Node类负责完成的。

3 获取数据长度:public int size()

在链表之中往往需要保存有大量数据,那么这些数据往往需要进行数据个数的统计操作,所以应该在LinkImpl子类里面追加有数据统计信息,同时当增加或删除数据时都应该对个数进行修改。
1、在ILink接口里面追加有一个获取数据的方法:

	public abstract int size();

2、在LinkImpl子类里面追加有一个个数统计的属性:

private int count;

3、在add()方法里面进行数据个数的追加:

public void add(E e){
		if(e == null){
			return ;
		}else{
			Node newNode = new Node(e);
			if( root == null ){
				root = newNode;
			}else{
				root.addNode(newNode);
			}
		}
		this.count++;
	}

4、需要在LinkImpl子类里面来返回数据的个数:

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

只是对于数据保存中的一个辅助功能。

4 空集合判断:public boolean isEmpty()

链表里面可以保存有若干个数据,如果链表没有保存数据,则链表为空,应该提供一个空集合判断。
1、在ILink接口里面追加有判断方法:

public boolean isEmpty();

2、在LinkImpl子类里面覆写此方法

public boolean isEmpty(){
		//return this.root == null;
		return this.count == 0;
	}

使用根节点或者长度的判断其本质是一样的。

5 返回集合数据:public Object[] toArray()

链表本身就属于一个动态对象数组,那么既然是一个对象数组,就应该可以把所有的数据以数组的形式返回来,那么接下来就可以定义一个toArray()方法,但是这个时候的方法只能够返回Object型的数组。
1、在ILink接口里面追加新的处理方法:

public Object[] toArray();

2、在LinkImpl子类里面追加两个属性:

private int foot;  //描述的是数组操作的脚标
private Object[] returnData;  //返回的数据保存

3、在Node中递归数据获取

public void toArrayNode(){
			LinkImpl.this.returnData[ LinkImpl.this.foot ++ ] = this.data;
			if( this.next != null ){
				this.next.toArrayNode();
			}
		}

3、在进行数据返回的时候一定要首先判断是否为空集合:

public Object[] toArray(){
		if(this.root == null){
			return null;
		}
		this.foot = 0;
		this.returnData = new Object[this.count];
		this.root.toArrayNode();
		return this.returnData;
	}

集合的数据一般如果要返回肯定要以对象数组的形式返回。

6 根据索引取得数据:public E get(int index)

链表可以像数组一样处理,也可像数组一样通过索引获取数据。
1、在ILink接口里面追加新的方法:

public E get(int index);

2、在Node类里面追加有根据索引获取数据的处理

public Node getNode(int index){
			if(index == 0){
				return this;
			}else{
				return this.getNode(index--);
			}
		}

3、在LinkImpl子类定义数据获取的实现

public E get(int index){
		if( index > this.count ){
			return null;
		}else{
			return this.root.getNode(index).data;
		}
	}

这一特点和数组是很相似的,但是需要注意的是,数组获取一个数据的时间复杂度为1,而链表获取数据的时间复杂度为n。

7 链表(修改指定索引数据):public void set(int index, E data)

现在可以根据索引来获取指定的数据了,但是既然可以获取数据,那么也可以进行数据的修改。
1、在ILink接口中增加新的方法

public void set(int index, E data);

2、在Node类之中提供数据修改支持

public void modifyNode(int index, E data){
			if(index == 0){
				this.data = data;
				return ;
			}else{
				this.next.modifyNode(--index, data);
			}
		}

3、在LinkImpl子类里面进行方法覆写

public void set(int index, E data){
		if(index > this.count || index < 0 ){
			return ;
		}else{
			this.root.modifyNode(index, data);
		}
	}

时间复杂度依然为n,因为需要遍历处理

8 链表(判断数据是否存在):public boolean contains(E data)

在一个集合里面往往会保存大量的数据,有些时候需要判断某个数据是否存在,这个时候就通过对象比较的模式来完成判断。
1、在ILink接口中追加判断方法:

public boolean contains(E data);

2、在Node类中进行依次判断

public boolean compare(E data){
			if( this.next == null ){
				return false;
			}else{
				if(this.data.equals(data)){
					return true;
				}else{
					return this.next.compare(data);
				}
			}
		}

3、在LinkImpl子类里实现此方法

public boolean contains(E data){
		if(data == null){
			return false;
		}else{
			return this.root.compare(data);
		}
	}

由于整个链表没有null数据的存在,所以整体的程序在判断的时候直接使用每一个节点数据发出equals()方法调用即可

9 链表(数据删除):public void remove(E data)

数据的删除指的是可以从集合里面删除指定的一个数据内容,也就是说此时传递的是数据内容,那么如果要实现这种删除操作,依然需要对象比较的支持,但是对于集合数据的删除我们需要考虑两种情况:
|——要删除的是根节点数据;
|——要删除的不是根节点数据。
1、在ILink节点增加新的删除方法

public void remove(E data);

2、在LinkImpl子类里面实现根节点的子类判断

public void remove(E data){
		if(data == null || this.root == null){
			return ;
		}else{
			if( this.root.data.equals(data) ){
				this.root = this.root.next;
			}
		}
}			

3、如果现在根节点并不是要删除的节点,那么就需要进行后续节点判断,但是请一定要记住,此时根节点已经判断完成,应从下一个节点开始判断,在Node类中追加删除处理:

public void delNode(Node prevNode,E data){
			if( this.next == null ){
				return ;
			}else{
				if(this.data.equals(data)){
					prevNode.next = this.next;
					return ;
				}else{
					this.next.delNode(prevNode.next, data);
				}
			}
		}

4、完善LinkImpl子类中的remove()方法

public void remove(E data){
		if(data == null || this.root == null){
			return ;
		}else{
			if( this.root.data.equals(data) ){
				this.root = this.root.next;
			}else{
				this.root.next.delNode(this.root, data);
			}
		}
		this.count--;
	}

删除的逻辑就是引用的处理完成。

10 链表(清空链表):public void clean()

有时候需要进行数据的整体清空处理,这个时候就可以直接根据根元素来进行控制,只要root设置为了null,那么后续的节点就都不存在了。
1、在ILink接口里追加清空处理方法

public void clean();

2、在LinkImple子类里面覆写方法

public void clean(){
		this.root = null;
		this.count = 0;
	}

这些就是链表的基本功能,当然,这只是一个最简单最基础的单向链表实现。

11 完整代码

个人代码:

interface ILink<E>{
	public abstract void add(E e);
	public abstract int size();
	public abstract boolean isEmpty();
	public abstract Object[] toArray();
	public abstract E get(int index);
	public abstract void set(int index, E data);
	public abstract boolean contains(E data);
	public abstract void remove(E data);
	public abstract void clean();
}

class LinkImpl<E> implements ILink<E>{
	private class Node{
		private E data;
		private Node next;

		public Node(){}

		public Node(E data){
			this.data = data;
			this.next = null;
		}

		public void addNode(Node newNode){
			if(this.next == null){
				this.next = newNode;
			}else{
				this.next.addNode(newNode);
			}
		}

		public void toArrayNode(){
			LinkImpl.this.returnData[ LinkImpl.this.foot ++ ] = this.data;
			if( this.next != null ){
				this.next.toArrayNode();
			}
		}

		public Node getNode(int index){
			if(index == 0){
				return this;
			}else{
				return this.next.getNode(--index);
			}
		}

		public void modifyNode(int index, E data){
			if(index == 0){
				this.data = data;
				return ;
			}else{
				this.next.modifyNode(--index, data);
			}
		}

		public boolean compare(E data){
			if( this.next == null ){
				return false;
			}else{
				if(this.data.equals(data)){
					return true;
				}else{
					return this.next.compare(data);
				}
			}
		}

		public void delNode(Node prevNode,E data){
			if( this.next == null ){
				return ;
			}else{
				if(this.data.equals(data)){
					prevNode.next = this.next;
					return ;
				}else{
					this.next.delNode(prevNode.next, data);
				}
			}
		}
	}

	private Node root = null;
	private int count = 0;
	private Object[] returnData;
	private int foot;

	public void add(E e){
		if(e == null){
			return ;
		}else{
			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.root == null){
			return null;
		}
		this.foot = 0;
		this.returnData = new Object[this.count];
		this.root.toArrayNode();
		return this.returnData;
	}

	public E get(int index){
		if( index > this.count || index < 0 || this.root == null){
			return null;
		}else{
			return this.root.getNode(index).data;
		}
	}

	public void set(int index, E data){
		if(index > this.count || index < 0 || this.root == null){
			return ;
		}else{
			this.root.modifyNode(index, data);
		}
	}

	public boolean contains(E data){
		if(data == null || this.root == null){
			return false;
		}else{
			return this.root.compare(data);
		}
	}

	public void remove(E data){
		if(data == null || this.root == null){
			return ;
		}else{
			if( this.root.data.equals(data) ){
				this.root = this.root.next;
			}else{
				this.root.next.delNode(this.root, data);
			}
		}
		this.count--;
	}

	public void clean(){
		this.root = null;
		this.count = 0;
	}
}

public class LinkDemo 
{
	public static void main(String[] args) {
		LinkImpl<String> link = new LinkImpl<String>();
		System.out.println("[1]元素数量:" + link.size());
		System.out.println("[1]集合是否为空:" + link.isEmpty());
		link.add("hhy");
		link.add("love");
		link.add("lks");
		link.add("forever");
		System.out.println("[2]元素数量:" + link.size());
		System.out.println("[2]集合是否为空:" + link.isEmpty());
		System.out.println("--------- [3]获取所有数据 ------------");
		Object[] obj = link.toArray();
		for(Object temp : obj){
			System.out.println(temp);
		}
		System.out.println("--------- [4]索引获取数据 ------------");
		System.out.println(link.get(0));
		System.out.println(link.get(1));
		System.out.println(link.get(3));
		System.out.println("--------- [5]索引修改数据 ------------");
		link.set(0, "lks");
		link.set(2, "hhy");
		Object[] obja = link.toArray();
		for(Object temp : obja){
			System.out.println(temp);
		}
		System.out.println("--------- [6]数据匹配 ------------");
		System.out.println(link.contains("lks"));
		System.out.println(link.contains("zsl"));
		System.out.println("--------- [7]数据节点删除 ------------");
		link.remove("lks");
		Object[] objb = link.toArray();
		for(Object temp : objb){
			System.out.println(temp);
		}
		System.out.println("--------- [8]数据清零 ------------");
		link.clean();
		System.out.println("[1]元素数量:" + link.size());
		System.out.println("[1]集合是否为空:" + link.isEmpty());
	}
}

视频代码:

interface ILink<E>{
	public abstract void add(E e);
	public abstract int size();
	public abstract boolean isEmpty();
	public abstract Object[] toArray();
	public abstract E get(int index);
	public abstract void set(int index, E data);
	public abstract boolean contains(E data);
	public abstract void remove(E data);
	public abstract void clean();
}

class LinkImpl<E> implements ILink<E>{
	private class Node{
		private E data;
		private Node next;

		public Node(){}

		public Node(E data){
			this.data = data;
			this.next = null;
		}

		public void addNode(Node newNode){
			if(this.next == null){
				this.next = newNode;
			}else{
				this.next.addNode(newNode);
			}
		}

		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( this.data.equals(data) ){ //对象比较
				return true;
			}else{
				if( this.next == null ){ //没有后续节点了
					return false;  //找不到
				}else{
					return this.next.containsNode(data);  //向后继续寻找
				}
			}
		}

		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 = null;  //保存根元素
	private int count = 0;  //保存数据个数
	private int foot;//描述的是操作数组的脚标
	private Object[] returnData;     //返回的数据保存

	//--------------以下为Link类中定义的方法-------------
	public void add(E e){
		if(e == null){
			return ;
		}else{
			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.root == null){
			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 || index < 0 || this.root == null){  //索引应在指定范围之内
			return null;
		}
		//索引数据的获取应该由Node类完成
		this.foot = 0;  //重置索引的下标
		return this.root.getNode(index);
	}

	public void set(int index, E data){
		if(index > this.count || index < 0 || this.root == null){  //索引应该在指定范围内
			return ;  //方法结束
		}
		//索引数据的获取应该由Node类完成
		this.foot = 0;
		this.root.setNode(index, data);  //修改数据
	}

	public boolean contains(E data){
		if(data == null || this.root == null){
			return false;  //没有数据
		}else{
			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;  //个数清零
	}
}

public class LinkDemo 
{
	public static void main(String[] args) {
		LinkImpl<String> link = new LinkImpl<String>();
		System.out.println("[1]元素数量:" + link.size());
		System.out.println("[1]集合是否为空:" + link.isEmpty());
		link.add("hhy");
		link.add("love");
		link.add("lks");
		link.add("forever");
		System.out.println("[2]元素数量:" + link.size());
		System.out.println("[2]集合是否为空:" + link.isEmpty());
		System.out.println("--------- [3]获取所有数据 ------------");
		Object[] obj = link.toArray();
		for(Object temp : obj){
			System.out.println(temp);
		}
		System.out.println("--------- [4]索引获取数据 ------------");
		System.out.println(link.get(0));
		System.out.println(link.get(1));
		System.out.println(link.get(3));
		System.out.println("--------- [5]索引修改数据 ------------");
		link.set(0, "lks");
		link.set(2, "hhy");
		Object[] obja = link.toArray();
		for(Object temp : obja){
			System.out.println(temp);
		}
		System.out.println("--------- [6]数据匹配 ------------");
		System.out.println(link.contains("lks"));
		System.out.println(link.contains("zsl"));
		System.out.println("--------- [7]数据节点删除 ------------");
		link.remove("lks");
		Object[] objb = link.toArray();
		for(Object temp : objb){
			System.out.println(temp);
		}
		System.out.println("--------- [8]数据清零 ------------");
		link.clean();
		System.out.println("[1]元素数量:" + link.size());
		System.out.println("[1]集合是否为空:" + link.isEmpty());
	}
}

11 综合实战(宠物商店)

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

1、应该定义出宠物的标准
2、宠物商店应该以宠物的标准为主
3、根据宠物标准定义宠物信息
4、实现宠物商店的操作

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

interface IPet{
	public abstract String getName();
	public abstract String getColor();
}

abstract class AbstractPet implements IPet{
	private String name;
	private String color;

	public AbstractPet(){}

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

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

	public void setColor(String color){
		this.color = color;
	}

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

	public String getColor(){
		return this.color;
	}

	public String toString(){
		return "name: " + this.name + ";  color: " + this.color + ";";
	}
}

class PetShop{
	private LinkImpl<IPet> allPets = new LinkImpl<IPet>();

	public void addPet(IPet pet){
		allPets.add(pet);
	}

	public void removePet(IPet pet){
		allPets.remove(pet);
	}

	public LinkImpl<IPet> searchPet(String keyword){
		LinkImpl<IPet> resultPets = new LinkImpl<IPet>();
		Object [] pets = allPets.toArray();
		if(pets != null){
			for(Object obj : pets){
				IPet temp = (IPet)obj;
				if(temp.getName().contains(keyword) || temp.getColor().contains(keyword)){
					resultPets.add(temp);
				}
			}
		}
		return resultPets;
	}
}

class Dog extends AbstractPet{
	
	public Dog(){}

	public Dog(String name, String color){
		super(name, color);
	}

	public String toString(){
		return "[pet dog]" + super.toString();
	}

	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.getName().equals(dog.getName()) && this.getColor().equals(dog.getColor());
	}
}

class Cat extends AbstractPet{
	public Cat(){}

	public Cat(String name, String color){
		super(name, color);
	}

	public String toString(){
		return "[pet cat]" + super.toString();
	}

	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.getName().equals(cat.getName()) && this.getColor().equals(cat.getColor());
	}
}


public class JavaDemo{

	public static void main(String[] args){
		PetShop petShop = new PetShop();
		Dog dog = new Dog("军犬", "黑色");
		petShop.addPet(new Cat("小花猫", "粉色"));
		petShop.addPet(new Cat("小黑猫", "浅黑色"));
		petShop.addPet(new Cat("波斯猫", "黑色"));
		petShop.addPet(new Cat("短尾猫", "深黑色"));
		petShop.addPet(dog);
		petShop.addPet(new Dog("牧羊犬", "绿色"));
		petShop.addPet(new Dog("斗牛犬", "棕色"));
		petShop.removePet(dog);
		Object[] pets = petShop.searchPet("黑").toArray();
		if( pets != null){
			for(Object obj : pets){
				IPet pet = (IPet)obj;
				System.out.println(pet);
			} 
		}
	}
}

12 综合实战(超市购物车)

使用面向对象的概念表示出下面的生活场景:小明去超市买东西,所有买到的东西都放在了购物车之中,最后到收银台一起结账。


1、定义出一个商品的标准

interface IGoods{  //定义商品标准
    public abstract String getName();
    public abstract double getPrice()
}

2、定义购物车处理标准

interface IShopCar{ //定义购物车标准
    public abstract void add(IGoods goods); //添加商品信息
    public abstract void delete(IGoods goods);  //删除商品
    public abstract Object[] getAll();  //获得购物车中的全部信息
}

3、定义购物车

class ShopCar implements IShopCar {
	private LinkImpl<IGoods> allGoods;

	public ShopCar(){  //无参构造
		this.allGoods = new LinkImpl<IGoods>();
	}

	public ShopCar(LinkImpl<IGoods> allGoods){  //单参构造
		this.allGoods = allGoods;
	}

	public void add(IGoods goods){   //添加商品
		this.allGoods.add(goods);
	}

	public void delete(IGoods goods){  //删除商品
		this.allGoods.remove(goods);
	}

	public int count(){
		return this.allGoods.size();
	}
	public Object[] getAll(){  //获得购物车中所有商品
		return this.allGoods.toArray();
	}
}

4、定义收银台

class Cashier{
	private IShopCar shopCar;

	public Cashier(){}  //

	public Cashier(IShopCar shopCar){
		this.shopCar = shopCar;
	}

	public double allPrice(){
		double sumPrice = 0.0;
		Object[] allGoods = this.shopCar.getAll();
		for(Object obj : allGoods){
			IGoods goods = (IGoods) obj;
			sumPrice += goods.getPrice();
		}

		return sumPrice;
	}

	public int allCount(){
		return this.shopCar.count();
	}

	public String settlement(){
		String result = "购物账单";
		Object[] allGoods = this.shopCar.getAll();
		for(Object obj : allGoods){
			IGoods goods = (IGoods) obj;
			result += "\n商品名称:" + goods.getName() + "商品价格:" + goods.getPrice();
		}
		return result + "\n总价:" + this.allPrice() + "总数: " + this.allCount();
	}
}

5、定义商品信息

class Book implements IGoods{
	private String name;
	private double price;

	public Book(){}

	public Book(String name, double price){
		this.name = name;
		this.price = price;
	}

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

	public double getPrice(){
		return this.price;
	}

	public boolean equals(Object obj){
		if(obj == null){
			return false;
		}
		if( !(obj instanceof Book) ){
			return false;
		}
		if( (Book)obj == this ){
			return true;
		}
		Book book = (Book)obj;
		return this.getName().equals(book.getName()) && this.getPrice()==book.getPrice();
	}

	public String toString(){
		return "商品名称:" + this.getName() + "商品价格:" + this.getPrice();
	}
}
class Bag implements IGoods{
	private String name;
	private double price;

	public Bag(){}

	public Bag(String name, double price){
		this.name = name;
		this.price = price;
	}

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

	public double getPrice(){
		return this.price;
	}

	public boolean equals(Object obj){
		if(obj == null){
			return false;
		}
		if( !(obj instanceof Bag) ){
			return false;
		}
		if( (Bag)obj == this ){
			return true;
		}
		Bag bag = (Bag)obj;
		return this.getName().equals(bag.getName()) && this.getPrice()==bag.getPrice();
	}

	public String toString(){
		return "商品名称:" + this.getName() + "商品价格:" + this.getPrice();
	}
}

6、完整代码

interface IGoods{
	public abstract String getName();
	public abstract double getPrice();
}

interface IShopCar{
	public abstract void add(IGoods goods);
	public abstract void delete(IGoods goods);
	public abstract int count();
	public abstract Object[] getAll();
}

class ShopCar implements IShopCar {
	private LinkImpl<IGoods> allGoods;

	public ShopCar(){  //无参构造
		this.allGoods = new LinkImpl<IGoods>();
	}

	public ShopCar(LinkImpl<IGoods> allGoods){  //单参构造
		this.allGoods = allGoods;
	}

	public void add(IGoods goods){   //添加商品
		this.allGoods.add(goods);
	}

	public void delete(IGoods goods){  //删除商品
		this.allGoods.remove(goods);
	}

	public int count(){
		return this.allGoods.size();
	}
	public Object[] getAll(){  //获得购物车中所有商品
		return this.allGoods.toArray();
	}
}

class Cashier{
	private IShopCar shopCar;

	public Cashier(){}  //

	public Cashier(IShopCar shopCar){
		this.shopCar = shopCar;
	}

	public double allPrice(){
		double sumPrice = 0.0;
		Object[] allGoods = this.shopCar.getAll();
		for(Object obj : allGoods){
			IGoods goods = (IGoods) obj;
			sumPrice += goods.getPrice();
		}

		return sumPrice;
	}

	public int allCount(){
		return this.shopCar.count();
	}

	public String settlement(){
		String result = "购物账单";
		Object[] allGoods = this.shopCar.getAll();
		for(Object obj : allGoods){
			IGoods goods = (IGoods) obj;
			result += "\n商品名称:" + goods.getName() + "商品价格:" + goods.getPrice();
		}
		return result + "\n总价:" + this.allPrice() + "总数: " + this.allCount();
	}
}

class Book implements IGoods{
	private String name;
	private double price;

	public Book(){}

	public Book(String name, double price){
		this.name = name;
		this.price = price;
	}

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

	public double getPrice(){
		return this.price;
	}

	public boolean equals(Object obj){
		if(obj == null){
			return false;
		}
		if( !(obj instanceof Book) ){
			return false;
		}
		if( (Book)obj == this ){
			return true;
		}
		Book book = (Book)obj;
		return this.getName().equals(book.getName()) && this.getPrice()==book.getPrice();
	}

	public String toString(){
		return "商品名称:" + this.getName() + "商品价格:" + this.getPrice();
	}
}
class Bag implements IGoods{
	private String name;
	private double price;

	public Bag(){}

	public Bag(String name, double price){
		this.name = name;
		this.price = price;
	}

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

	public double getPrice(){
		return this.price;
	}

	public boolean equals(Object obj){
		if(obj == null){
			return false;
		}
		if( !(obj instanceof Bag) ){
			return false;
		}
		if( (Bag)obj == this ){
			return true;
		}
		Bag bag = (Bag)obj;
		return this.getName().equals(bag.getName()) && this.getPrice()==bag.getPrice();
	}

	public String toString(){
		return "商品名称:" + this.getName() + "商品价格:" + this.getPrice();
	}
}

发布了77 篇原创文章 · 获赞 11 · 访问量 2636

猜你喜欢

转载自blog.csdn.net/weixin_43762330/article/details/104564556