ArrayList源码剖析
来源:互联网 发布:网络视频监控方案 编辑:程序博客网 时间:2024/06/06 19:49
构造函数:有3个构造函数
1)在jdk源码中ArrayList无参的构造函数,默认初始化大小是10;
2)带有指定大小参数的构造函数
3)带有集合参数的构造函数
一、确定ArrarList的容量
1、若ArrayList的容量不足以容纳当前的全部元素,设置新的容量 = (原始容量 * 3) / 2 + 1。
2、如果扩容后容量还是不够,则直接将minCapacity设置为当前容量。
public void ensureCapacity(int minCapacity) { // 将“修改统计数”+1,该变量主要是用来实现fail-fast机制的 modCount++; int oldCapacity = elementData.length; // 若当前容量不足以容纳当前的元素个数,设置新的容量=“(原始容量x3)/2 + 1” if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; //如果还不够,则直接将minCapacity设置为当前容量 if (newCapacity < minCapacity) newCapacity = minCapacity; elementData = Arrays.copyOf(elementData, newCapacity); } }
二、添加元素
public boolean add(E e) { ensureCapacity(size + 1); // 确定ArrayList的容量大小 elementData[size++] = e; // 添加e到ArrayList中 return true; }
将Element添加到ArrayList的指定位置
public void add(int index, E element) { if (index > size || index < 0) throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size); ensureCapacity(size+1); //确定ArrarList的容量 //将index位置及后面的元素都往后移一位 System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; //将e添加到index位置 size++; }
三、获取index位置的元素值
public E get(int index) { RangeCheck(index); return (E) elementData[index]; }
四、设置index位置的值为element
public E set(int index, E element) { RangeCheck(index); E oldValue = (E) elementData[index]; elementData[index] = element; return oldValue; }
五、删除ArrayList指定位置的元素
public E remove(int index) { RangeCheck(index); //检查索引index是否合理 modCount++; E oldValue = (E) elementData[index]; //保存要删除位置的元素 int numMoved = size - index - 1; //得到要移动的元素的个数 if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; //因为都往后移了一位,所以最后一个元素要置空 return oldValue; }
删除元素
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;} private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) //从"index+1"开始,用后面的元素替换前面的元素。 System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; //将最后一个元素设为nul }
六、ArrayList是否包含Object(o)
public boolean contains(Object o) { return indexOf(o) >= 0; }
正向查找,返回元素的索引值
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; } }
七、返回ArrayList的Object数组
public Object[] toArray() { return Arrays.copyOf(elementData, size); }
八、将集合c追加到ArrayList中
public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); //得到集合实际保存元素的数组 int numNew = a.length; ensureCapacity(size + numNew); //确定添加集合后ArrayList的容量合理 System.arraycopy(a, 0, elementData, size, numNew); //利用System.arraycopy方法将数组拷贝到ArrayList集合的数组中 size += numNew; return numNew != 0; }
分析ArrayList源码比较重要的几点总结:
1、ArrayList是如何确定容量的—->调用ensureCapacity方法。
2、ArrayList是基于数组的,所以获取元素和设置元素都是这样的形式:elementData[index],只需获取到数组索引就可以了。
3、在ArrayList源码中,大量使用了System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
src:源数组; srcPos:源数组要复制的起始位置; dest:目的数组; destPos:目的数组放置的起始位置; length:复制的长度。
比如ArrayList的增加、删除、将集合c追加到ArrayList中这三种操作,都使用了这个方法。
4、Arrays类的静态方法:copyOf(T[] original, int newLength)
original - 要复制的数组 ; newLength - 要返回的副本的长度 ; newType - 要返回的副本的类型
比如ArrayList的toArray()方法就使用了Arrays.copyOf方法。
- 【源码】ArrayList源码剖析
- java 源码ArrayList剖析
- ArrayList源码剖析
- ArrayList源码剖析
- ArrayList源码剖析
- C# ArrayList源码剖析
- Java ArrayList源码剖析
- ArrayList源码剖析
- ArrayList源码剖析
- ArrayList源码剖析
- Java ArrayList源码剖析
- ArrayList源码剖析
- 【Java】ArrayList源码剖析
- ArrayList源码剖析
- ArrayList源码简单剖析
- ArrayList源码剖析
- 【Java集合源码剖析】ArrayList源码剖析
- 【Java集合源码剖析】ArrayList源码剖析
- PLSQL连接oracel数据库_用户无法登陆_oci.dll_配置问题(32位64位问题)
- lufylegend引擎 rpg开发之2D地图的碰撞检测
- Android SDK更新 及 所有SDK文件共享
- 产品模式总结
- OpenCv3.0+SVM的使用心得(一)
- ArrayList源码剖析
- int *const p与int const *p的区别简析
- 第十六题
- 无法安装 Visual Studio 2010 Service Pack 1,因为此计算机的状态不支持
- _stdcall ,_cdecl,__fastcall 深入解析
- java基础1:异常
- JS验证控件jQuery Validate
- windows下获取mac地址的两种方法
- virtual析构函数