java动态数组实现(泛型)------数据结构

简单学习了数据结构基础,创建动态数组,将原有的静态数组,改变为动态数组。

接下来对动态数组的创建思路进行解释

构建俩个构造函数,可以指定capacity的大小来创建数组容量,若不传入参数,则默认容量为10

        private E[ ] data;
        private int size;
        //构造函数,传入数组的容量capacity构造Array
        public Array(int capacity) {
            data =(E[]) new Object [capacity];
            size =0;
        }
        
        //无参数的构造函数,默认数组的容量capacity=10 
        public Array() {
            this(10);
        }

 getsize方法返回数组的元素个数

//获取数组中的元素个数
        public int getsize() {
            return size;
        }

 getcapactiy方法返回数组的容量

//获取数组的容量
        public int getcapacity() {
            return data.length;
        }

isEmpty方法判断数组是否为空

    //返回数组是否为空
        public boolean isEmpty() {
            return size==0;
        }
        

find方法寻找元素e的索引,若e不存在则返回-1 

public int find (E e) {
            for(int i=0;i<size;i++) {
                if(e==data[i]) {
                    return i;
                }
            }
            return -1;
        }
         

   contains方法 查找数组中是否存在元素e

     public boolean contains (E e) {
            for(int i=0;i<size;i++) {
                if( data[i].equals(e)) {
                    return true;
                }
            }
            return false;
        }

   get方法获取index索引位置的元素

   if函数判断传入的参数是否合理

    public     E  get(int index) {
            if(index<0||index >size) {
                throw new IllegalArgumentException("Get failed.index is illegal");
            }
            return data[index];
        }

   set方法修改index索引位置的元素e

  void set(int index,E e) {
            if(index<0||index >size) {
                throw new IllegalArgumentException("Set failed.index is illegal");
            }
            data[index]  =e;
        }

 以上方法为数组的基本常用方法,但无法做到动态数组。

 以下方法将静态数组变为动态数组。

resize方法将数组变为可伸缩性

创建一个新的newData数组,将data数组的值赋值到newData数组中,最后将newData数组赋值给data数组,从而达到数组伸缩。

    private void resize(int newCapacity) {
            E[] newData= (E[])new Object [newCapacity];
            for(int i=0;i<size;i++) {
                newData[i] = data [i];
            }
            data=newData;       
        }
        

add方法在第index个位置插入一个新元素e

其中第一个if函数会判断传入的int参数是否正确,若不正确将抛出异常。

第二个if函数判断数组是否空余,若数组中的元素个数等于数组的容量,将数组扩容为原数组的二倍。

这里强调一下为什么要扩容为原来的二倍,而不是加一个常数。因为如果加一个常数,无法确定所加常数的大小。例如:所加常数大小为10,如果数组的原有长度为1000,将数组扩容之后数组的长度变为1010,扩容的10长度就会显得微不足道,可能会频繁调用resize方法,使代码的利用率不高。如果所加长度为1000,若原有长度为10,扩容之后将浪费很大一部分的内存,使代码的利用率不高。所以综上所述,将数组扩容为原来的2倍,最为合理。(当然也可以扩容为原来的x倍)

    //在第index个位置插入一个新元素
        public void add(int index,E e) {
            if(index<0||index >size) {
                throw new IllegalArgumentException("Add failed.Require index >=0 and index<=size.");
            }
            if(size==data.length) {
                resize(2*data.length);
            }
            for(int i=size-1;i>=index;i--) {
                data[i+1] = data[i]; 
            }
             data[index]=e;
             size++;
        }

remove方法从数组中删除index索引位置的元素,返回删除的元素

这里解释一下第二个if函数为什么当size==data.length/4时,将数组变为原来的1/2。

如果是size==data.length/2时,可能会频繁调用扩容方法。例如:原数组的容量为5,当加入第6个元素时,将会进行数组的扩容,数组容量变为原来的2倍。当扩容之后,删除第6个元素,会立马将数组容量变为1/2,当频繁进行添加删除操作,会频繁调用resize方法,使代码利用率降低。当size==data.length/4时,将数组变为原来的1/2,数组有1/2的长度为空,进行添加操作时,不会立马调用resize方法,从而使代码效率提高。


        public E remove(int index) {
            if(index<0||index >size) {
                throw new IllegalArgumentException("Remove failed.index is illegal");
            }
            E ret =data[index];
            for(int i=index+1;i<size;i++) {
                data[i-1]=data[i];
            }
            size--;
            data[size]=null;
            if(size==data.length/4&&data.length/2!=0) {
                resize(data.length/2);
            }
            return ret;
        }

最后将重写toString方法

public String toString() {
            StringBuilder res =new StringBuilder();
            res.append(String.format("Array: size=%d,capacity =%d\n",size,data.length));
            res.append("[");
            for(int i=0;i<size;i++) {
                res.append(data[i]);
                if(i!=size-1) {
                    res.append(",");
                }
            }
            res.append("]");
            return res.toString();  
            }

 这些方法是动态数组类中的主要方法,还可以添加一些方法,例如删除最后一个元素、删除第一个元素、再最后一个位置添加索引、再最前面添加索引。有一些方法还有bug,例如:find方法中只能找出e元素第一次出现的索引,数组是可以重复的,find方法还可以进行优化。其中使数组达到动态的方法为resize。此博客仅供参考,大家可以将各方法进行优化,加油!!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值