java abstractnumlist_JAVA语言-ArrayList实现原理

ArrayList简介

ArrayList就是动态数组,实现所有可选的列表操作,允许插入null值。当元素添加到ArrayList时,其容量会自动增长。未实现同步,可以用List list = Collections.synchronizedList(new ArrayList(...)),实现同步。

ArrayList继承

public class ArrayList extends AbstractList

implements List, RandomAccess, Cloneable, java.io.Serializable

ArrayList源码

一、构造函数[java] view plain copy

1.  //构造具有指定初始容量的空列表。

2.

3. public ArrayList(int initialCapacity) {

4.     if (initialCapacity > 0) {

5.         this.elementData = new Object[initialCapacity];

6.     } else if (initialCapacity == 0) {

7.         this.elementData = EMPTY_ELEMENTDATA;//空表

8.     } else {

9.         throw new IllegalArgumentException("Illegal Capacity: "+

10.                 initialCapacity);

11.     }

12. }

13.

14.  //构造一个初始容量为10的空列表。

15. public ArrayList() {

16.     this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

17. }

18.

19.

20.  //按照集合的迭代器返回的顺序构造包含指定集合的元素的列表。

21.

22. public ArrayList(Collection extends E> c) {

23.     elementData = c.toArray();

24.     if ((size = elementData.length) != 0) {

25.         // c.toArray 返回值不是Object[]

26.         if (elementData.getClass() != Object[].class)

27.             elementData = Arrays.copyOf(elementData, size, Object[].class);

28.     } else {

29.         // replace with empty array.

30.         this.elementData = EMPTY_ELEMENTDATA;

31.     }

32. }

由上面三种构造方法可知,默认情况下使用ArrayList会生成一个大小为10的Object类型的数组。

也可以使用下列构造函数确定初始容量的大小。[java] view plain copy

1. ArrayList(Collection extends E> c)

可以使用下列构造函数把容器转化为指定集合的元素的列表。[java] view plain copy

1. ArrayList(int initialCapacity)

二、其他方法

1、indexOf[java] view plain copy

1. public int indexOf(Object o) {

2.         if (o == null) {

3.             for (int i = 0; i 

4.                 if (elementData[i]==null)

5.                     return i;

6.         } else {

7.             for (int i = 0; i 

8.                 if (o.equals(elementData[i]))

9.                     return i;

10.         }

11.         return -1;

12.     }

2、clone

返回此 ArrayList 实例的浅拷贝。 (元素本身不被复制。)[java] view plain copy

1. public Object clone() {

2.         try {

3.             ArrayList> v = (ArrayList>) super.clone();

4.             v.elementData = Arrays.copyOf(elementData, size);

5.             v.modCount = 0;

6.             return v;

7.         } catch (CloneNotSupportedException e) {

8.             // this shouldn't happen, since we are Cloneable

9.             throw new InternalError(e);

10.         }

11.     }

3、toArray[java] view plain copy

1. public  T[] toArray(T[] a) {

2.         if (a.length 

3.             // 创建新数组

4.             return (T[]) Arrays.copyOf(elementData, size, a.getClass());

5.         System.arraycopy(elementData, 0, a, 0, size);//把elementData填入a中

6.         if (a.length > size)

7.             a[size] = null;

8.         return a;

9.     }

4、set

用指定的元素替换此列表中指定位置处的元素。[java] view plain copy

1. public E set(int index, E element) {

2.         rangeCheck(index);

3.

4.         E oldValue = elementData(index);

5.         elementData[index] = element;

6.         return oldValue;

7.     }

5、add

添加元素[java] view plain copy

1. public boolean add(E e) {

2.         ensureCapacityInternal(size + 1);  // Increments modCount!!

3.         elementData[size++] = e;

4.         return true;

5.     }

[java] view plain copy

1. public void add(int index, E element) {

2.         rangeCheckForAdd(index);

3.

4.         ensureCapacityInternal(size + 1);  // Increments modCount!!

5.         System.arraycopy(elementData, index, elementData, index + 1,

6.                          size - index);

7.         elementData[index] = element;

8.         size++;

9.     }

[html] view plain copy

1. public boolean addAll(Collection extends E> c) {

2.         Object[] a = c.toArray();

3.         int numNew = a.length;

4.         ensureCapacityInternal(size + numNew);  // 扩展容量

5.         System.arraycopy(a, 0, elementData, size, numNew);

6.         size += numNew;

7.         return numNew != 0;

8.     }

6、remove

移除元素[java] view plain copy

1. public E remove(int index) {

2.     rangeCheck(index);

3.

4.     modCount++;

5.     E oldValue = elementData(index);

6.

7.     int numMoved = size - index - 1;

8.     if (numMoved > 0)

9.         System.arraycopy(elementData, index+1, elementData, index,

10.                          numMoved);//把后面的元素迁移

11.     elementData[--size] = null; // clear to let GC do its work

12.

13.     return oldValue;

14. }

[java] view plain copy

1. public boolean remove(Object o) {

2.         if (o == null) {

3.             for (int index = 0; index 

4.                 if (elementData[index] == null) {

5.                     fastRemove(index);

6.                     return true;

7.                 }

8.         } else {

9.             for (int index = 0; index 

10.                 if (o.equals(elementData[index])) {

11.                     fastRemove(index);

12.                     return true;

13.                 }

14.         }

15.         return false;

16.     }

删除c中存在的元素[java] view plain copy

1. public boolean removeAll(Collection> c) {

2.         Objects.requireNonNull(c);

3.         return batchRemove(c, false);

4.     }

删除c中不存在的元素[java] view plain copy

1. public boolean retainAll(Collection> c) {

2.         Objects.requireNonNull(c);

3.         return batchRemove(c, true);

4.     }

其中batchRemove代码如下

complement=false时,删除c中存在的元素,反之删除c中不存在的元素[java] view plain copy

1. private boolean batchRemove(Collection> c, boolean complement) {

2.         final Object[] elementData = this.elementData;

3.         int r = 0, w = 0;

4.         boolean modified = false;

5.         try {

6.             //如果传入的集合c,包含当前所遍历的数组的元素,重新整理一下list中的元素

7.             for (; r 

8.                 if (c.contains(elementData[r]) == complement)

9.                     elementData[w++] = elementData[r];

10.         } finally {

11.             // Preserve behavioral compatibility with AbstractCollection,

12.             // even if c.contains() throws.

13.             if (r != size) {

14.                 System.arraycopy(elementData, r,

15.                                  elementData, w,

16.                                  size - r);

17.                 w += size - r;

18.             }

19.             if (w != size) {

20.                 // clear to let GC do its work

21.                 for (int i = w; i 

22.                     elementData[i] = null;

23.                 modCount += size - w;

24.                 size = w;

25.                 modified = true;

26.             }

27.         }

28.         return modified;

29.     }

7、clear[java] view plain copy

1. public void clear() {

2.         modCount++;

3.

4.         // clear to let GC do its work

5.         for (int i = 0; i 

6.             elementData[i] = null;

7.

8.         size = 0;

9.     }

二、内部类[java] view plain copy

1. private class Itr implements Iterator

2.

3. private class ListItr extends Itr implements ListIterator

4.

5. private class SubList extends AbstractList implements RandomAccess

6.

7. public Spliterator spliterator() {

8.         return new ArrayListSpliterator<>(this, 0, -1, 0);

9.     }

Itr是实现了Iterator接口,同时重写了里面的hasNext(),next(),remove()等方法;

ListItr继承Itr,实现了ListIterator接口,同时重写了hasPrevious(),nextIndex(),previousIndex(),previous()等方法。

SubList继承AbstractList,实现了RandmAccess接口,类内部实现了对子序列的增删改查等方法,但它同时也充分利用了内部类的优点,就是共享ArrayList的全局变量,例如检查器变量modCount,数组elementData等,所以SubList进行的增删改查操作都是对ArrayList的数组进行的,并没有创建新的数组。

Spliterator是一个可分割迭代器,是为了并行遍历元素而设计的一个迭代器,jdk1.8中的集合框架中的数据结构都默认实现了spliterator,具体没怎么了解。

希望这篇文章可以帮助到你,总之同学们,it资讯尽在职坐标。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值