2.动态数组

数组

  1. 数组是一种顺序存储的线性表,所有元素的内存地址都是连续的
    int[] array = new int[]{11, 12, 13}
  2. 在很多情况下我们定义了数组的长度后,便不能更改数组的长度,但我们确希望的数组的长度是能够动态变换的

动态数组的接口设计

  1. 创建ArrayList类,定义size属性来管理数组中元素的个数,定义elements(一个数组变量)属性来管理存取的数据
  2. 按照Java接口的设计思想,定义一些方法(即对数组的增删改查操作)

动态数组的实现

private int size;       //记录数组的长度
private E[] elements;   //用于存取数据的底层数组

//设置elements数组的默认初始化空间
private static final int CAPACITY_DEFAULT = 10;
//设置未找到变量时的默认值
private static final int ELEMENT_NOT_FOUND = -1;

//设置带参构造器
public ArrayList(int capacity) {
    capacity = Math.max(capacity, CAPACITY_DEFAULT);
    elements = (E[]) new Object[capacity];
}

//设置空参构造器,即:不自定义数组的长度
public ArrayList() {
    this(CAPACITY_DEFAULT);
}

/**
 * 一、数组元素的添加
 * 添加元素方法:
 *   分为两种情况:
 *   1.在最后一个元素的后面添加新的元素:只需将elements[size] = element,然后size加1即可
 *   2.在中间部位添加元素;需要将index只后的元素进行后移,注意:在移动前需要判断数组是否越界
 * @param index 添加元素索引
 * @param element 添加的元素
 */
public void add(int index, E element) {
    //判断越界
    rangeCheckForAdd(index);
    //判断是否需要扩容
    ensureCapacity();

    for (int i = size; i > index; i--) {
        elements[i] = elements[i - 1];
    }
    elements[index] = element;
    size++;
}

/**
 * add()重载方法:如果不指定索引,即:默认向最后位置添加元素
 */
public void add(E element) {
    add(size, element);
}

/**
 * 添加元素前需要判断索引是否越界,注意索引不能小于0,也不能大于size
 * @param index 添加元素的索引
 */
private void rangeCheckForAdd(int index) {
    if (index < 0 || index > size) {
        outOfBounds();
    }
}

/**
 * 二、数组越界
 * 数组越界抛出的异常信息
 */
private void outOfBounds() {
    throw new IndexOutOfBoundsException("索引越界");
}

/**
 * 三、数组扩容
 * 用来保证数组的长度是否还够(动态数组的核心-->数组扩容)
 */
private void ensureCapacity() {
    //获取数组当前容量
    int oldCapacity = elements.length;

    //如果当前储存元素个数 < 当前数组容量,直接返回
    if (size < oldCapacity) return;

    //新数组的容量是原数组的1.5倍
    int newCapacity = oldCapacity + (oldCapacity >> 1);

    //创建新数组
    E[] newElements = (E[]) new Object[newCapacity];

    //原数组中的数据储存到新数组中
    for (int i = 0; i < size; i++) {
        newElements[i] = elements[i];
    }

    //引用新数组
    elements = newElements;
}

/**
 * 四、数组元素删除
 * 删除元素时需要判断元素索引是否越界,即不能小于0,也不能大于等于size
 * 删除元素时只需用后一位元素覆盖前一位元素
 * 注意:思考最后一个元素怎么处理:只需最后一个元素复位空
 */
public E remove(int index) {
    //判断越界
    rangeCheck(index);
    //取出原来的元素,为返回做准备
    E old = elements[index];
    for (int i = index + 1; i < size; i++) {
        elements[i - 1] = elements[i];
    }
    //删除最后一个元素
    elements[--size] = null;  //--size既让数组长度减一又可以代表老数组的最后一个元素
    //将数组元素返回
    return old;
}

/**
 * 为删除元素服务的检查操作
 */
public void rangeCheck(int index) {
    if (index < 0 || index >= size) {
        outOfBounds();
    }
}

/**
 * 五、清空数组
 * 清空数组:只需所有元素的地址设为null, size设为0即可
 */
public void clear() {
    for (int i = 0; i < size; i++) {
        elements[i] = null;
    }
    size = 0;
}

/**
 * 六、设置元素
 * 修改元素:只需将该位置元素取出替换即可,同时需要注意判断索引是否越界
 * @return 返回被替换元素
 */
public E set(int index, E element) {
    //判断元素是否越界
    rangeCheck(index);
    //取出被替换的元素
    E oldElement = elements[index];
    //替换元素
    elements[index] = element;
    //返回被替换元素
    return oldElement;
}

/**
 * 七、查询元素
 * 查询元素,只需要将指定索引的元素返回,注意索引是否越界即可
 * @return 返回查出元素
 */
public E get(int index) {
    //判断是否越界
    rangeCheck(index);
    return elements[index];
}

/**
 * 八、获取元素索引
 * 可以通过循环, 查找元素在数组中的位置
 * 注意:假如数组中可以存储null,而null是不能调用equals方法的,所以需要对传入的元素进行判断,如果查找的元素是null
 * ,需要单独处理。
 * @return 返回索引或-1
 */
public int indexOf(E element) {
    if (element == null) {
        for (int i = 0; i < size; i++) {
            if (elements[i] == null) return i;
        }
    } else {
        for (int i = 0; i < size; i++) {
            if (element.equals(elements[i])) return i;
        }
    }
    return ELEMENT_NOT_FOUND;
}

/**
 * 九、判断元素是否为空
 * 只需判断索引是否为ELEMENT_NOT_FOUND
 */
public boolean contains(E element) {
    return indexOf(element) != ELEMENT_NOT_FOUND;
}

/**
 * 十、获取数组数量
 * @return size的值,即为元素的数量
 */
public int size() {
    return size;
}

/**
 * 十一、判断数组是否为空
 * @return 通过判断size的值是否为0即可判断数组是否为空
 */
public boolean isEmpty() {
    return size == 0;
}

/**
 * 十二、打印数组
 * 自定义如何输入动态数组
 */
public String toString() {
    StringBuilder string = new StringBuilder();
    string.append("size = ").append(size).append(", [");
    for (int i = 0; i < size; i++) {
        if (i != 0) {
            string.append(",");
        }
        string.append(elements[i]);
    }
    string.append("]");
    return string.toString();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值