首页 > 其他分享 >LinkedBox封装

LinkedBox封装

时间:2023-06-25 22:44:07浏览次数:35  
标签:Node index 封装 int node LinkedBox public size

类的设计 小任务
大家设计一个类ArrayBox
目的是 数组有些地方不是很好 长度固定 频繁添加元素 删除元素 个数改变

最早 利用数组存储一组元素
长度固定 好处在于创建后不会浪费内存
不好在于长度不变 添加删除时个数的改变很麻烦
自己可以设计类 ArrayBox
长度看似可以改变 好处在于添加 删除时不需要纠结长度变化的问题
不好在于 插入 删除效率低 不断的移动元素的位置进行覆盖
add get remove size


再设计一个类 LinkedBox 链表 链式 火车 联络网 小A<-->小B<-->小C<-->小D
长度看似可以改变
解决了插入和删除效率低的问题 不适合遍历
接口-----定义规则
多态

 

ArrayBox
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 - elementDate.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;
    }

}

  

LinkedBox
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(l==null){//如果原来尾节点没有对象 证明这个链表没有使用过的
            first = newNode;
        }else{//原来用过 刚才已经将新的节点连接在last之后啦
            l.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(index);
        //找到index位置的那个node
        Node targetNode = this.node(index);
        //设计一个小D同学  负责删除当前的目标节点  让他帮我们返回oldValue
        int oldValue = this.unlink(targetNode);
        return oldValue;
    }
    public int size() {
        return size;
    }
}

  

Node
package util;

public class Node {

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

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

  

Box
package util;

public interface Box {

    public boolean add(int element);
    public int get(int index);
    public int remove(int index);
    public int size();

}

  

BoxIndexOutOfBoundsException
package util;

public class BoxIndexOutOfBoundsException extends RuntimeException{

    public BoxIndexOutOfBoundsException(){}
    public BoxIndexOutOfBoundsException(String msg){
        super(msg);
    }
}

  

标签:Node,index,封装,int,node,LinkedBox,public,size
From: https://www.cnblogs.com/yonlanmoji/p/17504181.html

相关文章

  • 07前后端项目上传gitee,后端多方式登录接口,发送短信功能,发送短信封装,短信验证码接口,短
    1前后端项目上传到gitee#公司里: -前端一个仓库---》一个团队-后端一个仓库---》一个团队-微服务:两三个人一个服务---》一个项目一个仓库-网上开源软件,前后端都在一起#在远端建立前端仓库#本地代码提交到远成仓库2后端多方式......
  • 其他——25封装表单验证
    前言:在我们做vue项目,日常开发的时候,肯定会经常遇到正则表达式,例如手机号,邮箱,密码和数字,每次验证都需要去查询,浪费时间不说,也造成代码冗余,我也遇到过,那我就自己封装一个吧,方便大家使用查询。1.封装一个公共的js文件,命名rule.js://手机号验证telphone:(rule,value,callback......
  • 前端封装excel下载方法&&解决前端下载请求设置responseType: 'blob'时后台报错无法处
    请求设置responseType:'blob'时接口报错了如果不做处理则获取不到接口错误信息,此时下载的文件是有问题的。/*@paramsoptions{}*data:Blob,*fileName:String,*successMsg:String,**/import{Message}from'element-ui'importdownloadExcelFilePublicHandler......
  • 连接app的封装方法
    importpsutilfrompywinauto.applicationimportApplicationfrompywinautoimportDesktop,WindowSpecificationclassConnApp:@staticmethoddefconn_single_proc_app(proc_name:str,proc_path:str,app_backend:str="win32",......
  • Java基础之基本数据类型封装类的缓存
    巨人的肩膀:https://blog.csdn.net/hnjcxy/article/details/1237872091、Java中基本数据类型byte、short、char、int、long、float、double、boolean有对应的封装类型:Byte、Short、Character、Integer、long、Float、Double,Boolean其中Byte、Short、Character、Integer、Long、Bo......
  • 前端Vue自定义简单实用轮播图封装组件 快速实现轮播图
    前端Vue自定义简单实用轮播图封装组件快速实现轮播图,下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13153效果图如下:cc-mySwiper使用方法<!--自定义轮播图swiperArr:轮播数组 @swiperItemClick:轮播图条目点击--><cc-mySwiper:swi......
  • celery封装与包结构
    celery封装与包结构project├──celery_task #celery包│├──__init__.py#包文件│├──celery.py#celery连接和配置相关文件,且名字必须交celery.py│└──tasks.py#所有任务函数├──add_task.py #添加任务......
  • localStorage如何设置过期时间 (如何封装自定义localStorage)
    1、创建Storage类定义对应的getsetremoveclearapi通过set函数添加过期时间参数来实现过期时间的记录设置存储时存储当前值和过期时间get取值的时候先验证当前值是否存在以及时间是否大于过期时间如果存在且不大于过期时间既可返回对应的值否则返回空classStorage......
  • Android Kotlin Retrofit MVP网络请求封装(四)
    依赖implementation'com.squareup.retrofit2:retrofit:2.9.0'implementation'com.google.code.gson:gson:2.8.8'implementation'com.squareup.okhttp3:okhttp:4.9.1'implementation'com.squareup.retrofit2:retrof......
  • 【paramiko】基于paramiko封装SSH连接服务器执行命令
    1、官方文档paramiko·PyPIWelcometoParamiko’sdocumentation!—Paramikodocumentation 2、安装pipinstallparamiko 3、示例importparamiko#建立一个sshclient对象ssh=paramiko.SSHClient()#将信任的主机自动加入到host_allow列表,须放在connect......