动态java数组的实现思路

① 新建一个类DynamicArray

java 无长度array java无限长度数组_成员变量


② 考虑下动态数组需要哪些成员变量

/**
   * 元素的数量
   */
  private int size;
  /**
   * 所有的元素
   */
  private E[] elements;

E在集合中使用,因为集合中存放的是元素
② 构造方法
一开始指定可以存放多少个元素,通过构造方法,capaticy默认传入容量是多大。在java里面使用私有的常量就是通过static final的方式,java的编码规范常量一定要大写。静态的保证内存只占用一份。为了严谨,只要传递的数组数量小于10,就默认使用10,太小的不接受,如果传入1,很快就不够用了,很快就需要进行扩容了。

存在一个无参的构造方法调用有参的构造方法。java里面内部的方法调用使用this。

private static final int DEFAULT_CAPACITY = 10;
private static final int ELEMENT_NOT_FOUND = -1;
    public DynamicArray(int capaticy) {
        capaticy = (capaticy < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capaticy;
        elements = (E[]) new Object[capaticy];
    }
public DynamicArray() {
        this(DEFAULT_CAPACITY);
    }

③ 数组的数量
直接调用成员变量的size数量就可以。本身size的成员变量就是为了保存数组的数量。

/**
   * 元素的数量
   * @return
   */
  public int size() {
      return size;
  }

④ 数组的是否为空
直接看看size的数量是否等于0。

/**
     * 是否为空
     * @return
     */
    public boolean isEmpty() {
        return size == 0;
    }

⑤ 获取index的元素
在elements查找元素,但是index做一个约束,直接抽象出来一个方法rangeCheck,在java中比较常用的方式就是抛出数组越界一个异常IndexOutOfBoundsException。抛异常可以打印出来堆栈,可以直接直接异常存在的行,方便问题的定位。

可能你会想直接返回0算了,但是java里面比较正确的方式就是抛出异常,而不是返回一个假的值0。

/**
     * 获取index位置的元素
     * @param index
     * @return
     */
    public E get(int index) {
        rangeCheck(index);
        return elements[index];
    }
 private void rangeCheck(int index) {
        if (index < 0 || index >= size) {
            outOfBounds(index);
        }
    }
    private void outOfBounds(int index) {
        throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
    }

⑥ 设置index位置的元素返回原来的元素
找到原来的元素,然后通过index的位置覆盖新的元素。返回原来的元素。

/**
     * 设置index位置的元素
     * @param index
     * @param element
     * @return 原来的元素ֵ
     */
    public E set(int index, E element) {
        rangeCheck(index);
        E old = elements[index];
        elements[index] = element;
        return old;
    }
private void rangeCheck(int index) {
        if (index < 0 || index >= size) {
            outOfBounds(index);
        }
    }
    private void outOfBounds(int index) {
        throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
    }

⑦ 查看元素的索引
遍历从0这个位置,找到对应元素的位置,如果元素为null的话,找到对应null的位置,如果不等于null,就通过equals找到相同的元素,找到对应的位置,如果没找到返回-1,为了符合java的编码习惯这里将-1
定义为常量。

/**
     * 查看元素的索引
     * @param element
     * @return
     */
    public int indexOf(E element) {
        if (element == null) {  // 1
            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; // n
            }
        }
        return ELEMENT_NOT_FOUND;
    }

⑧ 是否包含某个元素
直接返回的位置是不是等于-1就可以了。

/**
     * 是否包含某个元素
     * @param element
     * @return
     */
    public boolean contains(E element) {
        return indexOf(element) != ELEMENT_NOT_FOUND;
    }

⑨ 清除所有的元素
为什么不直接size =0,却还要先将里面的元素for循环设置成null呢?设置null作用释放内存空间。其实可以不使用for,写for是为了代码严谨。很多时候清理内存才是浪费性能,放在那里等待垃圾回收它就好了

/**
     * 清除所有元素
     */
    public void clear() {
        for (int i = 0; i < size; i++) {
            elements[i] = null;
        }
        size = 0;
    }