手动实现ArrayList动态数组

手动实现动态数组

作者q:2835916127
blog:博主博客

线性表

数据结构: 计算机存储组织数据的方式
线性表: 具有n个相同元素的有限序列(n>=0)
a1 -> a2 -> a3 -> a4 -> … -> an
a1: 首节点、(首元素)
an: 尾节点(尾元素)

  • a1是a2的前驱节点
  • a2是a1的后继节点

常见的线性表:

  1. 数组
  2. 链表
  3. 队列
  4. 哈希表(散列表)
    ……
  • 数组是一种顺序存储的线性表,所有元素的内存地址是连续的

需要知道的一些

  • 变量名是存储在栈中的

  • new 出来的对象是存储在堆中的

  • java中成员变量自动初始化,比如:

    • int初始化为0
    • 对象初始化为null
  • 重写toString()自定义打印数组

  • StringBuilder可以拼接字符串

Object[] ob = new Object[7];
  • 对象数组
    • ob -> 栈空间
    • ob[i] -> 堆空间
    • ob[i] 里并非对象本身,而是对象的引用(即地址)
int [] array = new int[10]{
    
    11,22,33};

实例:

背景: 在许多语言开发中数组都有个致命缺点—数组一旦创建,容量不可变,然而我们都希望数组长度可以动态变化
需求 :底层采用数组 实现动态扩容数组(ArrayList)
目的:

  1. 体会线性结构
  2. 练习常用算法
  3. 强化数组
  4. 练习泛型

面对的问题:

  • 数组一旦创建,容量不可变
  • 扩容的条件
  • 如何处理空值

动态数组接口设计

int size(); // 元素的数量boolean isEmpty(); // 是否为空boolean contains(E element); // 是否包含某个元素void add(E element); // 添加元素到最后面
◼ E get(int index); // 返回index位置对应的元素
◼ E set(int index, E element); // 设置index位置的元素void add(int index, E element); // 往index位置添加元素
◼ E remove(int index); // 删除index位置对应的元素int indexOf(E element); // 查看元素的位置void clear(); // 清除所有元素

具体实现:

package cn.dreamyi.demo;

/**
 * 动态可变数组  自动扩容
 * qq:2835916127
 */
public class DynamicArray<E> {
    
    
    private int size = 0;//保存当前元素长度

    //定义默认初始化容量
    private final int DEFAULT_CAPACITY = 10;

    //查找失败返回值
    private final int ELEMENT_NOt_FOUND = -1;
    //用于保存数组元素
    private E[] elements = (E[]) new Object[DEFAULT_CAPACITY];

    /**
     * 检查索引越界
     *
     * @param index 当前访问索引
     */
    private void checkIndex(int index) {
    
    
        if (index < 0 || index >= size) {
    
    
            throw new IndexOutOfBoundsException("索引越界" + "允许范围 size:0 => " + (size - 1) + " 当前索引:" + index);
        }
    }

    /**
     * 检查添加索引越界
     *
     * @param index 添加位置的索引
     */
    private void checkAddIndex(int index) {
    
    
        if (index < 0 || index > size) {
    
    
            throw new IndexOutOfBoundsException("索引越界" + "允许范围 size:0 => " + (size) + " 当前索引:" + index);
        }
    }

    /**
     * 确保数组容量够用
     */
    private void ensureCapacity() {
    
    
        //扩容1.5倍
        E[] newElements = (E[]) new Object[elements.length + (elements.length >> 1)];

        for (int i = 0; i < size; i++) {
    
    
            newElements[i] = elements[i];
        }
        elements = newElements;//引用
    }

    public DynamicArray() {
    
    
    }

    /**
     * 带参初始化
     *
     * @param capacity 初始化容量
     */
    public DynamicArray(int capacity) {
    
    
        if (capacity < 10) {
    
    
            elements = (E[]) new Object[DEFAULT_CAPACITY];
        } else {
    
    
            elements = (E[]) new Object[capacity];
        }
    }

    /**
     * 返回当前元素的数量
     *
     * @return 当前元素的个数
     */
    public int size() {
    
    
        return size;
    }

    /**
     * 当前数组是否为空
     * 空:true
     * 非空:false
     *
     * @return 返回true | false
     */
    public boolean isEmpty() {
    
    
        return size == 0;
    }

    /**
     * 是否包含某个元素
     *
     * @param element
     * @return 返回true | false
     */
    public boolean contains(E element) {
    
    
        if (element == null) {
    
    
            for (int i = 0; i < size; i++) {
    
    
                if (elements[i] == null) return true;
            }
        } else {
    
    
            for (int i = 0; i < size; i++) {
    
    
                if (element.equals(elements[i])) return true;
            }
        }
        return false;
    }

    /**
     * 添加元素到尾部
     *
     * @param element 待添加的元素
     */
    public void add(E element) {
    
    
        if (size > elements.length - 1) {
    
    
            ensureCapacity();
        }
        elements[size++] = element;
    }

    /**
     * 返回对应索引的值 不存在返回-1
     *
     * @param index 元素的索引
     * @return 对应值 | -1
     */
    public E get(int index) {
    
    
        checkIndex(index);

        return elements[index];
    }

    /**
     * 设置index位置元素的值
     *
     * @param index   需要设置的位置索引
     * @param element 设置的值
     * @return 返回原先的值
     */
    public E set(int index, E element) {
    
    
        checkIndex(index);//检查索引越界

        E old = elements[index];
        elements[index] = element;

        return old;
    }


    /**
     * 向index位置添加元素
     *
     * @param index   插入位置的索引
     * @param element 插入的元素
     */
    public void add(int index, E element) {
    
    
        checkAddIndex(index);//检查索引越界

        for (int i = size; i > index; i--) {
    
    
            elements[i] = elements[i - 1];//把元素右移
        }
        elements[index] = element;
        size++;
    }

    /**
     * 移除index位置元素
     *
     * @param index 被移除元素的索引
     * @return 返回原先值
     */
    public E remove(int index) {
    
    
        checkIndex(index);
        E old = elements[index];

        for (int i = index; i < size; i++) {
    
    
            elements[i] = elements[i + 1];
        }
        elements[--size] = null;//清空最后一个元素
        return old;
    }

    /**
     * 查找元素
     *
     * @param element 需要查找的元素
     * @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;
    }

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

    /**
     * 返回元素集合size:5, [1, 3, 4 ,5 ,7 ]
     *
     * @return
     */
    @Override
    public String toString() {
    
    
        StringBuilder sb = new StringBuilder("size:" + size + " => [");
        for (int i = 0; i < size; i++) {
    
    
            if (i != 0) {
    
    
                sb.append(" ,");
            }
            sb.append(elements[i]);
        }
        sb.append("]");
        return sb.toString();
    }
}

主函数中调用

   public static void main(String[] args) {
    
    
//      System.out.println(feb2(45));
        DynamicArray<String> list = new DynamicArray(1);
       list.add("sdas");
       list.add("32143");
        DynamicArray<Student> stuList = new DynamicArray<>();
        Student st1 = new Student("001", "张三", "19");
        Student st2 = new Student("002", "李四", "23");
        Student st3 = new Student("001", "赵六", "25");
        stuList.add(st1);
        stuList.add(null);
        System.out.println(stuList.contains(null));
        System.out.println(stuList.indexOf(null));
        stuList.add(st2);
        stuList.add(st3);


        System.out.println(stuList.toString());
//        System.out.println(list.toString());

总结:见上面

猜你喜欢

转载自blog.csdn.net/weixin_42143994/article/details/109709272