LinkedBox封装

  • 类的设计 小任务
  • 设计一个类ArrayBox
    目的是 数组有些地方不是很好 长度固定 频繁添加元素 删除元素 个数改变
    最早 利用数组存储一组元素
    长度固定 好处在于创建后不会浪费内存
    不好在于长度不变 添加删除时个数的改变很麻烦

自己可以设计类 ArrayBox
长度看似可以改变 好处在于添加 删除时不需要纠结长度变化的问题
不好在于 插入 删除效率低 不断的移动元素的位置进行覆盖
add get remove size

public class ArrayBox implements Box{
属性用来存储真实数据elementDate[]
属性用来记录有效元素个数 int size;
public boolean add(element){
//1.确保数组内部容量
//2.将element元素存入数组的最后位置 size++
//3.返回一个true告知用户添加成功
}
public int get(index){
//1.检测index范围是否合法
//2.将index位置的元素从数组中取出来,并返回
}
public int remove(index){
//1.检测index范围是否合法
//2.获取iindex位置上的元素----保留起来
//3.从index开始至size-1位置 将后面元素啄一前移覆盖
//4.最后有效的那个元素删掉 —size
//5.保留起来的旧元素返回
}
public int size(){
//return this.size;
}
}

再设计一个类 LinkedBox 链表 链式 火车 联络网 小A<–>小B<–>小C<---->小D
长度看似可以改变
解决了插入和删除效率低的问题 不适合遍历
//这是一个自定义的类型–节点
public class Node{
Node prev;
int item;
Node next;
}
public class LinkedBox implements Box{
属性存储首节点first
属性存储尾节点last
属性存储有效元素的个数size
public boolean add(element){
//找一个人 将element添加在链表末尾
//告知添加成功
}
public int get(index){
//检测index是否合法
//找一个人 帮我们找到index位置的那个Node对象
//将node中item数据返回
}
public int remove(index){
//检测index是否合法
//找一个人 帮我们找到index位置的那个Node对象
//找一个人 帮我们将node对象删除 将删掉node对象中的旧数据返回
//将旧数据返回
}
public int size(){
返回有效元素的个数
}
}

  • 接口----定义规则

public interfaace Box{
public boolean add(element);//添加到末尾
public void add(int index,int element);//在给定的位置中插入一个元素
public void addAll();//将给定的box中所有的元素添加至我们现在的box中
public int get();
public int remove();
public int size();
}
有了box可以做统一的规则约束
每一个人子类都实现同一个规则 用户使用起来很容易
如果按照上述的方式来实现 规则添加了新的方法 所有的子类都跟着添加新的方法

package util;
public class ArrayBox implements Box{

	//设计一个静态常量  用来存储数组的默认长度
	private static final int DEFAULT_CAPACITY=10;
	//设计一个自己的属性  用来存放真实数据的
	private int[] elementDate;
	//设计一个自己的属性  用来记录数组内存储的有效元素个数
	private int size=0;

	//构造方法重载
	public ArrayBox(){
		elementDate=new int[DEFAULT_CAPACITY];
	}
	public ArrayBox(int capacity){
		elementDate=new int[capacity];
	}
	
	//小A同学  负责确保数组内部的容量
	private void ensureCapacityInternal(int minCapacity){
		//判断如果你需要的最小容量比原数组的长度还要大
		if(minCapacity-elemetDate.length>0){
			//需要进行数组的扩容  找别人计算扩容的大小
			this.grow(minCapacity);
		}
	}
	//小B同学  负责计算扩容大小
	private void grow(int minCapacity){
		//获取原数组的长度
		int oldCapacity=elementDate.length;
		//小B同学帮我做了一个计算  在原数组之上增加1.5倍
		int newCapacity=oldCapacity+(oldCapacity>>1);
		//比较计算后的长度与所需的长度
		if(newCapacity-minCapacity<0){
			//那么直接按照所需的长度作为新数组的长度
			newCapacity= minCapacity;
		}
		//调用小C同学  让他创建新数组  将原数组中的所有元素移入新数组中
		elementDate = this.copyOf(elementDate,newCapacity);
	}
	//小C同学  负责将原数组中的元素移入新数组中
	private int[] copyOf(int[] oldArray,int newCapacity){
		//按照提供的长度创建一个新数组
		int[] newArray=new int[newCapacity];
		//将原数组中的元素按照位置移入新数组中
		for(int i=0;i<oldArray.length;i++){
			newArray[i]=oldArray[i];
		}
		//将新数组返回
		return newArray;
	}
	
	//小D同学  检测给定index是否合法
	private void  rangeCheck(int index){
		if(index<0 || index >=size ){
			//自定义一个异常 来说明问题
			throw new BoxIndexOutOfBoundsException("Index:"+index+:",Size:"+size);
		}
	}
	
	//==============================================================================
	//用来将用户给定的element存起来  参数是需要存起来的元素  返回值是否存储成功
	public boolean add(int element){
		//找一个别人  做事   确保数组内部容量够用
		this.ensureCapacityInternal(size+1);
		//上述一行代码可以执行完毕  证明elementDate的数组肯定够用
		//直接将新来的element元素存入数组中  并且让size多记录一个
		elementDate[size++] =element;
		//返回true告知用户存储元素成功
		return true;
	}
	//用来获取给定位置的元素  参数是索引位置  返回值是取得的元素
	public int get(int index){
		//找一个小弟,检测给定的index是否合法
		this.rangeCheck(index);
		//上述代码可以执行,证明index是合法的
		//则找到index对应位置的元素  将其返回
		return elementDate[index];
	}
	//用来删除给定位置的元素  参数是索引位置  返回值是删除掉的那个元素
	public int remove(int index){
		//调用小D同学  检测index
		this.rangeCheck(index);
		//上述代码可以执行  index是合法的
		//找到index位置的元素  保留起来  留给用户
		int oldValue=elementDate[index];
		//1 2 3 4 5 6    size==6个
		//1 2 4 5 6 0    elementDate[5]=0    size-1
		//从index位置开始至size-1结束  后面元素依次前移覆盖
		for(int i=index;i<size-1;i++){
			elementDate[i]=elementDate[i+1];
		}
		//手动将最后的元素删除  让size减少一个记录
		elementDate[--size] =0;
		//将旧数据返回
		return oldValue;
	}
	//设计一个方法  用来获取size有效的个数  没有设置  可以保护size的安全
	public int size(){
		return size;
	}
}
package util;
public class BoxIndexOutOfBoundsException extends RuntimeException{
	
	public BoxIndexOutOfBoundsException(){}
	public BoxIndexOutOfBoundsException(String msg){
		super(msg);
	}
}
package util;

public interface Box{
	public boolean add(int element);
	public int get(int index);
	public remove(int index);
	public size();
}
package util;

public class LinkedBox implements Box{
	
	//创建几个属性
	private Node first;//记录首节点
	private Node last;//记录尾结点
	private int size;//记录有效元素的个数

	//设计一个小A同学  负责将元素添加在新的node里  挂在链表的尾端
	private void linkLast(int element){
		//获取链表的尾节点
		Node l=last;
		//创建一个新的node对象  将新数据包装起来
		Node newNode=new Node(l.element,null);
		//将新节点对象设置为尾节点
		last=newNode;
		//严谨的判断
		if(1==null){//如果原来尾节点没有对象  证明这个链表没有使用过的
			first=newNode;
		}else{//原来勇用过  刚才已经将新的节点连接在last之后啦
			1.next=newNode;
		}
		//有效元素个数增加一个
		size++;
	}
	//设计一个小B同学 负责检测index
	private void rangeCheck(int index){
		if(index<0 ||  index>=size){
			throw new BoxIndexOutOfBoundsException("Index:"+index+",Size:"+size);
		}
	}
	//设计一个小C同学  负责找寻给定index位置的node对象
	private Node node(int index){
		Node targetNode;//用来存储找到的当前那个目标
		//判断index范围是在前半部分  还是在后半部分
		if(index < (size>>1)){//从前往后找寻比较快
			targetNode=first;
			for(int i=0;;i<index;i++){
				targetNode=targetNode.next;
			}
		}else{//从后往前找
			targetNode=last;
			for(int i=size-1;i>index;i--){
				targetNode=targetNode.prev;
			}
		}
		return targetNode;
	}
	//设计一个方法 小D同学 负责将给定的node节点对象删除  并且保留数据
	private int unlink(Node targetNode){
		//获取当前node的item信息---
		int oldValue=targetNode.item;
		//当前node的前一个
		Node prev=targetNode.prev;
		//当前node的下一个
		Node next=targetNode.next;
		//删除节点对象
		if(prev==null){//当前node就是第一个
			first=next;
		}else{
			prev.next=next;
			targetNode.prev=null;
		}
		if(next==null){//当前node就是最后一个
			last=prev;
		}else{
			next.prev=prev;
			targetNode.next=null;
		}
		//让有效元素减少一个
		size--;
		return oldValue;
	}

	//========================================================
	//数据结构
	public boolean add(int element){
		//将element存入一个新的Node对象里  添加至链表的尾端
		this.linkLast(element);
		//告知添加成功
		return true;
	}
	public int get(int index){
		//检测index是否合法
		this.rangeCheck(index);
		//找寻index对应位置的那个node对象 将对象中的数据取出来
		Node targetNode=this.node(index);
		//返回找到的node对象内数据
		return targetNode.item;
	}
	public int  remove(int index){
		//检测范围是否合法
		this.rangeCheck(inde);
		//找到index位置的那个node
		Node rargetNode=this.node(index);
		//设计一个小D同学  负责删除当前的目标节点  让他帮我们返回OldValue
		int oldValue=this.unlink(targetNode);
		return oldValue;
	}
	public int size(){
		return 0;
	}
}
package util;

public class Node{
	public Node prev;//previous
	public int item;//当前的数据
	public Node next;//下一个node对象

	public Node(Node prev,int item,Node next){
		this.prev=prev;
		this.item=item;
		this.next=next;
	}
}

在这里插入图片描述

package test;

import util.*;

public class TestMain{
	public static  void main(String[] args){
		ArrayBox ab=new ArrayBox();
		ab.add(10);
		ab.remove(0);
		ab.get(0);
		ab.size();

		LinkedBox lb=new LInkedBox();
		lb.add(10);
		int v2=lb.remove(0);
		int v3=lb.get(0);
		lb.size();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值