美文网首页
二、动态数组简单实现

二、动态数组简单实现

作者: 你大赟哥 | 来源:发表于2020-12-05 22:56 被阅读0次

1.1设计动态数组:

  • 添加、删除,清空,等接口设计
  • 设计为泛型、这样任何对象都能够使用
  • 动态增加倍数、使用位移运算增加效率
  • 清空数组时,使用for循环设置每个元素为null,保留原数组,这样能够减少开辟新数组的情况
  • 泛型存放的是对象,与存方简单的Int类型,存在内存处理问题
  • indexof查找对比时使用equals方法而不是使用‘=’号,这样数组中的对象比较的是该对象内部equals方法。
  • null的处理:是否允许数组存取null,null的存取代码不需要改动,不能的话设计null判断,并做处理(null时用‘==’,非null使用equals)。
  • 大量移动可以使用java的arraycopy提高效率

1.2动态数组代码:

@SuppressWarnings("unchecked")
public class ArrayList<E> {
    /**
     * 元素的数量
     */
    private int size;
    /**
     * 所有的元素
     */
    private E[] elements;
    
    private static final int DEFAULT_CAPACITY = 10;
    private static final int ELEMENT_NOT_FOUND = -1;
    
    public ArrayList(int capaticy) {
        capaticy = (capaticy < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capaticy;
        elements = (E[]) new Object[capaticy];
    }
    
    public ArrayList() {
        this(DEFAULT_CAPACITY);
    }
    
    /**
     * 清除所有元素
     */
    public void clear() {
        for (int i = 0; i < size; i++) {
            elements[i] = null;
        }
        size = 0;
    }

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

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

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

    /**
     * 添加元素到尾部
     * @param element
     */
    public void add(E element) {
        add(size, element);
    }

    /**
     * 获取index位置的元素
     * @param index
     * @return
     */
    public E get(int index) {
        rangeCheck(index);
        return elements[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;
    }

    /**
     * 在index位置插入一个元素
     * @param index
     * @param element
     */
    public void add(int index, E element) {
        rangeCheckForAdd(index);
        
        ensureCapacity(size + 1);
        
        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) {
        rangeCheck(index);
        
        E old = elements[index];
        for (int i = index + 1; i < size; i++) {
            elements[i - 1] = elements[I];
        }
        elements[--size] = null;
        return old;
    }

    /**
     * 查看元素的索引
     * @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;
    }
    
//  public int indexOf2(E element) {
//      for (int i = 0; i < size; i++) {
//          if (valEquals(element, elements[i])) return i; // 2n
//      }
//      return ELEMENT_NOT_FOUND;
//  }
//  
//  private boolean valEquals(Object v1, Object v2) {
//      return v1 == null ? v2 == null : v1.equals(v2);
//  }
    
    /**
     * 保证要有capacity的容量
     * @param capacity
     */
    private void ensureCapacity(int capacity) {
        int oldCapacity = elements.length;
        if (oldCapacity >= capacity) 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;
        
        System.out.println(oldCapacity + "扩容为" + newCapacity);
    }
    
    private void outOfBounds(int index) {
        throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
    }
    
    private void rangeCheck(int index) {
        if (index < 0 || index >= size) {
            outOfBounds(index);
        }
    }
    
    private void rangeCheckForAdd(int index) {
        if (index < 0 || index > size) {
            outOfBounds(index);
        }
    }
    
    @Override
    public String toString() {
        // size=3, [99, 88, 77]
        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]);
            
//          if (i != size - 1) {
//              string.append(", ");
//          }
        }
        string.append("]");
        return string.toString();
    }
}

1.2注意点:
1.2.1扩容后、元素赋值


Snip20201205_11.png

1.2.2清空和移除(设置为空和位置)

Snip20201205_18.png

相关文章

  • 二、动态数组简单实现

    1.1设计动态数组: 添加、删除,清空,等接口设计 设计为泛型、这样任何对象都能够使用 动态增加倍数、使用位移运算...

  • 数据结构——栈

    目录 1、定义 2、实现 2.1 简单数组实现 2.1.1 代码实现 2.1.2 性能和局限性 2.2 动态数组实...

  • 动态数组底层是如何实现的

    动态数组底层是如何实现的 2.1 动态数组的位置 目标: 简单认识下继承关系 ArrayList继承于Abstra...

  • C语言 泛型动态数组

    泛型实现思路:万能指针void *动态数组实现思路:动态进行数组内存的扩容 realloc 泛型动态数组 数组可以...

  • ArrayList的使用及ConcurrentModificat

    ArrayList是一种动态数组,可以动态的增加或删除元素。ArrayList和Vector都是用数组实现的,但二...

  • 栈的基本实现

    基于动态数组的实现

  • C语言动态数组

    一维动态数组 二维动态数组

  • 数组,哈希表,字符串

    1,数组 1.1,实现一个动态扩容的数组 1.2,实现一个大小固定的有序数组,支持动态增删改操作 1.3,实现两个...

  • 数组 字符串 2019-04-11

    数组 要求 实现一个支持动态扩容的数组 实现一个大小固定的有序数组,支持动态增删改操作 实现两个有序数组合并为一个...

  • 常用算法目录

    数组 实现一个支持动态扩容的数组 实现一个大小固定的有序数组,支持动态增删改操作 实现两个有序数组合并为一个有序数...

网友评论

      本文标题:二、动态数组简单实现

      本文链接:https://www.haomeiwen.com/subject/dbenwktx.html