java动态数组实现

定义动态数组类

public class DynamicArray{
}

一个动态数组,需要的参数有:

  • size -逻辑大小
  • capacity -容量
  • array -静态数组

size看已经添加了多少个元素,是否超出容量。
capacity能够存储多少个元素
array添加元素实际上是往这里面添的

public class DynamicArray{
    private int size = 0;// 逻辑大小
    private int capacity = 8;// 容量
    private int[] array = {};
}

添加方法

向最后位置添加元素

我们只需要在数组已经有的最后一个元素对应的索引的后一个索引也就是size的位置中赋值传进来的数值就好了。

 /**
  * 向最后位置[size]添加元素
  * @param element 待添加元素
  */
 public void addLast(int element){
    array[size] = element;
    //添加了一个元素,长度加1
    size++;
 }

向指定索引添加元素

我们只需要让指定索引后的所有元素集体向后移动,在赋值元素到指定的索引即可

    /**
     * 向[0 .. size]位置添加元素
     * @param index 索引位置
     * @param element 待添加元素
     */
    public void add(int index,int element){
        //添加逻辑
        if(index >= 0 && index < size) {
            //向后移动,空出待插入位置
            System.arraycopy(array, index, array, index + 1, size - index);
        }
        array[index] = element;
        size++;
    }

但是这样有一个问题。

如果我们开始定义的数组中已经填满了,怎么办?

我们还需要定义容量检查和扩容方法

容量检查和扩容方法

我们只需要用if else判断来判断是否需要扩容

如果size == 0,因为我们最开始定义的静态数组并没有实现真正的容量,所以如果size==0我们为实现这个数组,这种方式称之为懒加载

如果size==capacity,说明已经满了需要扩容

  1. 首先让容量加上它的0.5倍,我们每次扩容1.5倍
  2. 定义一个新的数组
  3. 将原来数组的数据拷贝到新的数组中
  4. 将原来的数组指向到新的数组
private void checkAndGrow() {
        //容量检查
        if(size == 0){
            array = new int[capacity];
        } else if(size == capacity){
            //进行扩容 1.5 1.618 2
            //我们扩容1.5倍
            capacity += capacity >> 1;
            int[] newArray = new int[capacity];
            System.arraycopy(array,0,newArray,0,size);
            array = newArray;
        }
    }

有了扩容方法,我们的添加方法才算完成

    /**
     * 向最后位置[size]添加元素
     * @param element 待添加元素
     */
    public void addLast(int element){
        checkAndGrow();
        array[size] = element;
        //添加了一个元素,长度加1
        size++;
    }

    /**
     * 向[0 .. size]位置添加元素
     * @param index 索引位置
     * @param element 待添加元素
     */
    public void add(int index,int element){
        checkAndGrow();
        //添加逻辑
        if(index >= 0 && index < size) {
            //向后移动,空出待插入位置
            System.arraycopy(array, index, array, index + 1, size - index);
        }
        array[index] = element;
        size++;
    }

 删除方法

删除方法就是让被指定要删除的元素的索引位置的后面的元素向前移,覆盖掉要删除的元素

public int remove(int index){
        int removed = array[index];
        if(index < size - 1) {
            System.arraycopy(array, index + 1, array, index, size - index - 1);
        }
        size--;
        return removed;
    }

获取方法

    /**
     * 获取指定索引中的元素
     * @param index 索引
     * @return 指定索引中的元素
     */
    public int get(int index){
        return array[index];
    }

遍历方法

foreach

我们在参数中实现一个叫Consumer<T>的类,实现调用者可以自己对循环的参数进行操作

    /**
     * 遍历方法1
     * @param consumer 遍历要执行的操作,入参:每个元素
     */
    public void foreach(Consumer<Integer> consumer){
        for (int i = 0; i < size; i++){
            consumer.accept(array[i]);
        }
    }

迭代器

迭代器需要实现Iterable<T>的接口

public class DynamicArray implements Iterable<Integer>{
    /**
     * 遍历方法2 -迭代器遍历
     */
    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            int i = 0;
            @Override
            public boolean hasNext() {  //有没有下一个元素
                return i < size;
            }

            @Override
            public Integer next() { //返回当前元素,并移动到下一个元素
                return array[i++];
            }
        };
    }
}

hasNext方法:此方法用来判断是否有下一个元素
        如何判断是否还有没有下一个元素,定义第一个元素的索引,如果 i 还小于长度说明有下一个元素

next方法:此方法用来返回当前元素,并移动到下一个元素
        返回当前元素即 return array[i] , 移动到下一个元素为i++
        正好后++为先执行语句在执行自增
        所以我们可以直接写成return array[i++];

完整代码

/**
 * 动态数组
 */
public class DynamicArray implements Iterable<Integer>{
    private int size = 0;// 逻辑大小
    private int capacity = 8;// 容量
    private int[] array = {};

    /**
     * 向最后位置[size]添加元素
     * @param element 待添加元素
     */
    public void addLast(int element){
        checkAndGrow();
        array[size] = element;
        //添加了一个元素,长度加1
        size++;
    }

    /**
     * 向[0 .. size]位置添加元素
     * @param index 索引位置
     * @param element 待添加元素
     */
    public void add(int index,int element){
        checkAndGrow();
        //添加逻辑
        if(index >= 0 && index < size) {
            //向后移动,空出待插入位置
            System.arraycopy(array, index, array, index + 1, size - index);
        }
        array[index] = element;
        size++;
    }

    private void checkAndGrow() {
        //容量检查
        if(size == 0){
            array = new int[capacity];
        } else if(size == capacity){
            //进行扩容 1.5 1.618 2
            //我们扩容1.5倍
            capacity += capacity >> 1;
            int[] newArray = new int[capacity];
            System.arraycopy(array,0,newArray,0,size);
            array = newArray;
        }
    }

    public int remove(int index){
        int removed = array[index];
        if(index < size - 1) {
            System.arraycopy(array, index + 1, array, index, size - index - 1);
        }
        size--;
        return removed;
    }

    /**
     * 获取指定索引中的元素
     * @param index 索引
     * @return 指定索引中的元素
     */
    public int get(int index){
        return array[index];
    }

    /**
     * 遍历方法1
     * @param consumer 遍历要执行的操作,入参:每个元素
     */
    public void foreach(Consumer<Integer> consumer){
        for (int i = 0; i < size; i++){
            consumer.accept(array[i]);
        }
    }

    /**
     * 遍历方法2 -迭代器遍历
     */
    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            int i = 0;
            @Override
            public boolean hasNext() {  //有没有下一个元素
                return i < size;
            }

            @Override
            public Integer next() { //返回当前元素,并移动到下一个元素
                return array[i++];
            }
        };
    }
}


                      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值