zoukankan      html  css  js  c++  java
  • ArrayList实现

    数组实现
    父类:AbstractList
    接口:List,RandomAccess,Cloneable,Serializable
    字段:
    //默认容量
    private static final int DEFAULT_CAPACITY = 10;
    //空的数组,构造函数参数为0和trim中使用,构造参数给0的人绝对会被打死,每放一个元素,就要重新copy一次
    private static final Object[] EMPTY_ELEMENTDATA = {};

    //实际保存数组,transient,这个字段不用写入流
    transient Object[] elementData
    //实际元素数目
    private int size;

     public ArrayList(int initialCapacity) 
    {
            if (initialCapacity > 0) 
           {
                this.elementData = new Object[initialCapacity];
            } 
            else if (initialCapacity == 0) 
            {
              //注意初始容量为0时给的对象,EMPTY_ELEMENTDATA
                this.elementData = EMPTY_ELEMENTDATA;
            }
             else 
             {
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                   initialCapacity);
            }
     }
    
    
     public ArrayList()
     {
              //默认构造函数
            this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
     }
    
     public ArrayList(Collection<? extends E> c) 
    {
           //转入的集合转换为数组
            elementData = c.toArray();
          //改变自己的size
            if ((size = elementData.length) != 0) 
           {
               //这里有个坑,可能不能正确的返回Object[] Class对象,不能的话复制
                // c.toArray might (incorrectly) not return Object[] (see 6260652)
                if (elementData.getClass() != Object[].class)
                    elementData = Arrays.copyOf(elementData, size, Object[].class);
            } else 
            {
                // replace with empty array.
                this.elementData = EMPTY_ELEMENTDATA;
            }
      }
    
    //截断,在原数组上移动
    public void trimToSize() 
    {
            modCount++;
            if (size < elementData.length) 
           {
                elementData = (size == 0)
                  ? EMPTY_ELEMENTDATA
                  : Arrays.copyOf(elementData, size);
            }
     }
    
    //比较关心的几个方法,存放,取出,查找
    //查找,运行时间上界O(n),从这里也可用看出是允许放null
    public int indexOf(Object o) 
    {
            if (o == null) 
           {
                for (int i = 0; i < size; i++)
                    if (elementData[i]==null)
                        return i;
            } else 
            {
                for (int i = 0; i < size; i++)
                    if (o.equals(elementData[i]))
                        return i;
            }
            return -1;
      }
    
    //反向查找
     public int lastIndexOf(Object o) 
    {
            if (o == null) 
             {
                for (int i = size-1; i >= 0; i--)
                    if (elementData[i]==null)
                        return i;
            } else 
            {
                for (int i = size-1; i >= 0; i--)
                    if (o.equals(elementData[i]))
                        return i;
            }
            return -1;
     }
    //返回index位置的元素
    E elementData(int index) 
    {
            return (E) elementData[index];
     }
    
    //获取对应位置元素,O(1)
     public E get(int index) 
    {
           //检查size,并没有判断小于0
            rangeCheck(index);
            return elementData(index);
    }
    
    //将元素放在对应位置,index<size,list当成数组使用,注意,这样的代码会报错
    //List<String> list = new ArrayList<>(100);
    //		list.set(10, "123");
    //根据构造函数可以知道,已经开辟了100长度的数组,但是就是不让你用
     public E set(int index, E element) 
    {
            rangeCheck(index);
            E oldValue = elementData(index);
            elementData[index] = element;
            return oldValue;
    }
    
    
    private void grow(int minCapacity) 
    {
            // overflow-conscious code
            int oldCapacity = elementData.length;
            //原来的1.5备长度
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            // minCapacity is usually close to size, so this is a win:
           //注意是新开辟一个数组给elementData
            elementData = Arrays.copyOf(elementData, newCapacity);
     }
    
    
     private void ensureExplicitCapacity(int minCapacity) 
    {
            modCount++;
    
            // overflow-conscious code
            //1-0,进入if,进行内存复制,开辟新的数组
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
    }
    
    
    private void ensureCapacityInternal(int minCapacity) 
    {
           //构造函数给0,这里是false
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) 
            {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
             
            //ensureExplicitCapacity(1);
            ensureExplicitCapacity(minCapacity);
     }
    
    //增加一个元素
     public boolean add(E e) 
     {
           //为什么构造函数给0会被打死,看下面这个函数,一来就要新数组,新的数组长度也只有1
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            elementData[size++] = e;
            return true;
     }
    
    //元素放到index位置,0<=index<size
    public void add(int index, E element) 
    {
            rangeCheckForAdd(index);
    
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            System.arraycopy(elementData, index, elementData, index + 1,
                             size - index);
            elementData[index] = element;
            size++;
    }
    //移除
     public E remove(int index) 
    {
            rangeCheck(index);
    
            modCount++;
            E oldValue = elementData(index);
    
            int numMoved = size - index - 1;
        //内存复制
            if (numMoved > 0)
                System.arraycopy(elementData, index+1, elementData, index,
                                 numMoved);
            elementData[--size] = null; // clear to let GC do its work
    
            return oldValue;
    }
    //O(n)的移除,注意在fastRemove方法里面也会出现内存复制
    public boolean remove(Object o) 
    {
            if (o == null) 
            {
                for (int index = 0; index < size; index++)
                    if (elementData[index] == null) 
                    {
                        fastRemove(index);
                        return true;
                    }
            } else {
                for (int index = 0; index < size; index++)
                    if (o.equals(elementData[index])) {
                        fastRemove(index);
                        return true;
                    }
            }
            return false;
     }
    
    //为什么elementData不用置null,方便重用
    public void clear() 
    {
            modCount++;
            // clear to let GC do its work
            for (int i = 0; i < size; i++)
                elementData[i] = null;
            size = 0;
     }
    
    
    
    //浅克隆
    public Object clone() 
    {
            try {
                ArrayList<?> v = (ArrayList<?>) super.clone();
                v.elementData = Arrays.copyOf(elementData, size);
                v.modCount = 0;
                return v;
            } catch (CloneNotSupportedException e) {
                // this shouldn't happen, since we are Cloneable
                throw new InternalError(e);
            }
      }
    
    //返回副本
     public Object[] toArray() 
    {
            return Arrays.copyOf(elementData, size);
    }
    
    
    
    
    结尾附上一个内存分布的代码,有指针真好
    int main(int argc, char* argv[])
    {
    	//int ba[4];
    	int a[] = { 1, 2, 3, 4 };
    	int c = 5;
    	int d = 6;
    	int dd = 7;
    	cout << a << endl;
    	cout << a[-1] << endl;
    	cout << a-1 << endl;
    	cout<<&dd<<endl;
    	cout << &d << endl;
    	cout << &c << endl;
    	//memcpy(ba, a, sizeof(int) * 4);
    	//cout << ba[0] << endl;
    	//cout << ba[1] << endl;
    	return 0;
    }
    

      

  • 相关阅读:
    CAF(C++ Actor Framework)介绍
    Android C++打印函数调用栈
    80%应聘者都不及格的JS面试题
    二叉树的最近公共祖先--递归解法
    mysql的InnoDB引擎的行记录格式ROW_FORMAT
    Docker安装mysql 集群(pxc方式)及负载均衡实践
    主机ping不通虚拟机,虚拟机可以ping通主机解决方式
    springboot源码解析
    springmvc源码解析
    寻找两个正序数组的中位数
  • 原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/7502877.html
Copyright © 2011-2022 走看看