Niefajun的技术点滴

niefajun

数据结构-数组02-动态数组介绍

60
2025-02-08

1.整体介绍

java自带的数组,默认是静态数组,在创建的时候,大小就固定好了,不能插入或者删除元素,使用起来有一定的局限性。与之对应的是动态数组,在使用的过程中可以插入和删除元素。

实际java中已经有实现好的动态数组ArrayList,为了深刻理解,还是自己手动实现一个动态数组,理解其中的原理。

思路:
所谓动态数组,并不是说创建一个新的动态数据的数据类型。而是再普通静态数组的基础上面,用面向对象的方式,扩充属性,实现类似动态数组数组的效果。数据存储还是使用静态数据来实现。

2.动态数组类说明

2.1 动态数组类基本属性

动态数组类基本属性:

  • size: 代表数组中有效的元素个数。初始为0.添加元素就增大,删除元素就变小。
  • capacity: 代表数组容量,就是数组最多可以放多少元素。类似ArrayList的初始容量为10.并且会有一定的扩容策略。
  • array: 静态数组真实数组,用于实际存储数据。默认值new int[capacity],对应不同数据类型。

动态数据类的基本结构:

public class DynamicArray {
    /**
     * 动态数组逻辑大小,代表数组中有效元素的数目
     */
    private int size = 0;

    /**
     * 动态数组的容量,容量正常情况下都是>=size
     * 当容量==size,还需要继续添加元素,就需要扩容了。
     * java中arrayList中的初始容量是10
     */
    private int capacity = 10;

    /**
     * 静态数组,动态数组本质内部还是静态数组支持底层存储
     */
    private int[] array = new int[capacity];
}  

2.2 末尾添加元素.

思路比较简单,就是把数组最后一个元素进行赋值操作,同时增加size的大小。

目前还没有扩容部分的程序,后面统一实现扩容之后再补充。

@Deprecated
public void addLastHistoryV1(int element) {
    // todo 目前还是一个简单版本,没有考虑扩容的问题
    // 原始版本
    this.array[size] = element;
    size++;
}

2.3 通用添加元素方法

目前还没有扩容部分的程序,后面统一实现扩容之后再补充。

原始版本:
按照插入元素的位置,分三种情况进行处理。

@Deprecated
public void addHistoryV1(int index, int element) throws ArrayIndexOutOfBoundsException {
    // todo 目前还是一个简单的版本,没有考虑扩容的问题
    // 原始版本
    if (index >= 0 && index < size) {
        System.arraycopy(this.array, index, this.array, index + 1, size - index);
        this.array[index] = element;
        size++;
    } else if (index == size) {
        this.array[size] = element;
        size++;
    } else {
        throw new ArrayIndexOutOfBoundsException();
    }
}

调整版本:
首先对于超出超出边界的情况进行单独处理。
然后末尾插入index=size元素实际是index<size插入元素的一种特殊情况,对两种情况进行合并。

public void add(int index, int element) throws ArrayIndexOutOfBoundsException {
    // todo 目前还是一个简单的版本,没有考虑扩容的问题
    // 修改版本
    if (index < 0 || index > size) {
        throw new ArrayIndexOutOfBoundsException();
    }
    if (index < size) {
        System.arraycopy(this.array, index, this.array, index + 1, size - index);
    }
    this.array[index] = element;
    size++;
}

2.4 遍历元素的三种方式

第一种方式: 直接for循环遍历打印
是最简单,最直接的方式,但功能单一,复用性低

/**
 * 最原始的打印方法,就只有打印一个功能,功能单一
 */
public void foreach() {
    for (int i = 0; i < size; i++) {
        System.out.println(array[i]);
    }
}

第二种方式: 使用函数式接口来实现
相比直接的for循环,将遍历的内容交给

第三种方式: 通过实现Iterable类使用增强for循环遍历

  • 0