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;
    }
    

      

  • 相关阅读:
    mysql 远程登陆不上
    hdu 5339 Untitled【搜索】
    SqlServer 书目
    passwordauthentication yes
    oracle 11g RAC ocfs2
    Oracle 11g RAC database on ASM, ACFS or OCFS2
    CentOS ips bonding
    Oracle 11g RAC features
    openStack 王者归来之 trivial matters
    openstack windows 2008 img
  • 原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/7502877.html
Copyright © 2011-2022 走看看