• 封装一个ArrayBox--实际是ArrayList的底层简单实现


    package arrayBox;
    
    /**
     * 设计一个类,可以新增,删除,获取元素
     * 
     * @author my 数组存储数据 ArrayBox存储 int[] arr=new int[10] ArrayBox box=new Array()
     *         arr[0]=5 box.add(5);
     *         分析:作为用户而言,arraybox的好处是,1.不需关心索引,自动管理存在哪个位置,0号位置,或者1号位置
     *         。2.不需要关心长度,不用担心存不下
     * 
     */
    public class ArrayBox<E>{//泛型
        private Object[] elementData;// 在box内部还是使用数组进行存储
        private int size = 0;// 记录有效元素个数
        private static final int DEFAULT_CAPACITY=10;//默认长度
        public ArrayBox(){
            elementData=new Object[DEFAULT_CAPACITY];
        }
        //这两个构造方法的作用是让用户可以自己使用默认的长度,或者自定义
        public ArrayBox(int capacity){
            elementData=new Object[capacity];
        }
        /**
         * 添加元素
         * 
         * @param element
         */
        public boolean add(E element) {
            // 添加元素之前,首先得确保可以存的下
            this.ensureCapacity(size+1);// 这里采用的是一个一个加的,所以需要的最小长度就是,原有效个数基础上加一个
            // 如果上面这句代码执行没问题,要么空间够,不需要扩容,直接在旧数组中插入一个元素,要么不够,进行扩容复制到新数组后,指向旧数组,再插入
            elementData[size++] = element;// 第一次是0号位置存储,并自增记录有效个数
            return true;// 返回true表示存储成功
    
        }
        /**
         * 获取元素
         * @param index
         * @return
         */
        public Object get(int index){
            //先检查index是否合法 >=0 <=size
            this.rangeCheck(index);
            return elementData[index];
        }
        /**
         * 删除元素
         * 需要删除的那个元素索引
         * return 删除的那个元素
         */
        public Object remove(int index) {
            this.rangeCheck(index);
            //先將index位置的旧值保存起来、
            Object oldValue=elementData[index];
            //删除的方法是遍历后一个元素覆盖前一个元素
            //10.20.30.40.50.60.0000
            //10 20 40 40 50 60 0000 
            //10 20 40 50 50 60 0000
            //10 20 40 50 60 60 0000
            //10 20 40 50 60 0  0000 
            /*这种写法会导致一个问题,就是如果有效元素个数刚刚填满数组,那么遍历最后一次将最后一个元素用有效元素之外的0覆盖时数组越界
            for(int i=index;i<size;i++){
                elementData[i]=elementData[i+1];
            }
            */
            for(int i=index;i<size-1;i++){
                elementData[i]=elementData[i+1];
            }
            elementData[--size]=0;//避免了上诉写法的数组越界,记录有效元素-1,并将最后一个元素,这里是60,替换为0
            return oldValue;//返回删除的元素给用户
            
        }
        private void rangeCheck(int index){
            if(index<0 || index>=size){
                throw new BoxIndexOutOfBoundsException();//new一个自定义的异常对象,把它抛出来
            }
        }
    
    
        /**
         * 确保容量够用,目前我们声明的数组是10个长度,那么得比较存入的长度是否超过10
         * 
         * @return
         */
        private void ensureCapacity(int minCapacity) {
            if (minCapacity - elementData.length > 0) {
                // 需要的最小长度比原数组长度还大,需要扩容
                this.grow(minCapacity);
    
            }
    
        }
        /**
         * 扩容
         * @param minCapacity
         */
        private void grow(int minCapacity) {
            int oldCapacity = elementData.length;// 原数组长度
            int newCapacity = oldCapacity + oldCapacity >> 1;// 这里扩容1.5倍。乘法不是乘以2的倍数,底层效率,位运算更高
            if (newCapacity - minCapacity < 0) {// 新计算得到的长度仍然比需要的最小长度小,那么直接赋值需要的最小长度作为新新数组长度
                newCapacity = minCapacity;
            }
            // 按照上面的计算得到一个newCapacity,创建一个新数组,将旧数组的东西全部复制到新数组,把旧数组的名字给新数组用
            this.elementData = this.copyOf(elementData, newCapacity);
    
        }
        /**
         * 创建一个新数组,将旧数组的值复制到新数组
         * @param oldArray
         * @param newCapacity
         * @return array
         */
        private Object[] copyOf(Object[] oldArray, int newCapacity) {
            Object[] newArray = new Object[newCapacity];
            for (int i = 0; i < oldArray.length; i++) {
                newArray[i] = oldArray[i];
            }
            return newArray;
        }
    
    }
    package arrayBox;
    
    
    public class Test {
    
        public static void main(String[] args) {
            ArrayBox box =new ArrayBox();
            box.add(10);
        
        }
    
    }
    
    package arrayBox;
    /**
     * 自定义异常类
     * @author my
     *
     */
    public class BoxIndexOutOfBoundsException extends RuntimeException{
        public BoxIndexOutOfBoundsException(){
            
        }
        public BoxIndexOutOfBoundsException(String msg){
            super(msg);//调用父类的带参构造方法
        }
    }
  • 相关阅读:
    ASP.NE网站发布注意事项
    jQuery中使用$.ajax提交表单
    DataTable类Clone及Copy方法的区别
    DataList控件使用初步
    一个非常标准的Java连接Oracle数据库的示例代码
    详细解析用C#写的小游戏《彩色连珠》(附源代码)
    VS 2010 复制代码到word出现乱码解决办法
    Java之简单的图片动态显示(实现类似GIF动画效果)
    Class.forName(String driverClassName)加载JDBC驱动程序时,底层都做了些什么???
    Java设计好看的窗体必加的代码(使用内置皮肤控件):
  • 原文地址:https://www.cnblogs.com/hebiao/p/12564798.html
Copyright © 2020-2023  润新知