美文网首页
关于ArrayList

关于ArrayList

作者: 瓢鳍小虾虎 | 来源:发表于2021-08-02 12:38 被阅读0次

    ArrayList简介

    1. ArrayList内部是以动态数组存放数据的,所谓动态数组,不是数组本身可以改变长度,而是保留原有数组引用的情况下创建一个新的数组,使用体验就像是可自动扩容的数组。
    2. ArrayList内部是数组,支持数组的所有特性,通过索引支持随机访问,所以访问效率高,但是插入和删除效率低下。
    3. ArrayList实现了AbstractList抽象类、List接口、所以其更具有了AbstractList和List的功能,AbstractList内部已经实现了获取Iterator和ListIterator的方法,所以ArrayList只需关心对数组操作的方法即List接口的实现。
    4. ArrayList实现了RandomAccess接口、此接口只有声明、没有方法体、表示ArrayList支持随机访问。
    5. ArrayList实现了Cloneable接口、此接口只有声明、没有方法体、表示ArrayList支持克隆。
    6. ArrayList实现了Serializable接口、此接口只有声明、没有方法体、表示ArrayList支持序列化、即可以将ArrayList以流的形式通过ObjectInputStream/ObjectOutputStream来写/读。

    ArrayList的扩容

    1. 初始容量为10:使用无参构造的创建ArrayList的时候默认容量为10。
    2. 扩容规则:每次add元素(单个或者一组)的时候,都要先检查容量是否够用。如果发现容量不够,就设置新容量为原有容量1.5倍+1,如果新容量还不够用,就直接把新容量设置为能盛放当前元素量的值。然后就是使用Arrays.copyOf()方法把原数据copy到新数组中去。由此可见,使用ArrayList尽量明确使用上限,自动扩容虽好,但是效率不高。
    3. 为什么是1.5倍:跟源代码中的算法有关“oldCapacity + (oldCapacity >> 1);”
    4. Arrays.copyOf():最终使用的是操作系统的api进行数组复制,效率比我们手写代码要高。
    5. 扩容限制:扩容并非是无限制的,有内存限制,虚拟机限制。

    手写ArrayList帮助理解

    public class MyArrayList<T> implements Iterable<T>  {
        private T[] theItems;
        private int theSize;
        private static final int DEAULT_CAPACITY=10;
    
        public MyArrayList(){
            theSize=0;
            ensureCapacity(DEAULT_CAPACITY);
    
        }
    
        public void add(T data){
            if(size()==theItems.length){
                ensureCapacity(size()*2+1);
            }
            theItems[size()]=data;
            theSize++;
        }
    
        public void add(int index,T data){
            if(size()==theItems.length){
                ensureCapacity(size()*2+1);
            }
            for(int i=theSize;i>index;i--){
                theItems[i]=theItems[i-1];
            }
            theItems[index]=data;
            theSize++;
        }
    
        public T get(int index){
            if(index<0|index>=size()){
                throw new IndexOutOfBoundsException("index error");
            }
            return theItems[index];
        }
    
        public T remove(int index){
            T removeData=get(index);
            for(int i=index;i<size()-1;i++){
                theItems[i]=theItems[i+1];
            }
            theSize--;
            return removeData;
        }
    
        public int size(){
            return theSize;
        }
    
        private void ensureCapacity(int newCapacity){
            if(theSize>newCapacity){
                return;
            }
    
            T[] old=theItems;
            theItems= (T[]) new Object[newCapacity];
            for(int i=0;i<size();i++){
                theItems[i]=old[i];
            }
        }
    
    
    
        @Override
        public Iterator<T> iterator() {
            return null;
        }
    
        @Override
        public void forEach(Consumer<? super T> action) {
    
        }
    
        @Override
        public Spliterator<T> spliterator() {
            return null;
        }
    }
    

    参考文章:
    Java容器之ArrayList

    相关文章

      网友评论

          本文标题:关于ArrayList

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