ArrayList实现

Posted 菜菜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

  

 

以上是关于ArrayList实现的主要内容,如果未能解决你的问题,请参考以下文章

获取 Intent 片段上的 Serializable ArrayList

包含不同片段的HashMap(或ArrayList)

面试常用的代码片段

回收站视图未显示在片段中

从ViewPager android替换片段

无法更新FragmentPagerAdapter中的片段