集合源码分析----ArrayList
来源:互联网 发布:淘宝支付限额怎么改 编辑:程序博客网 时间:2024/06/08 04:31
分析基于JDK1.7
ArrayList是基于数组实现的,但是底层涉及了很多细节,先看下ArrayList的主要成员
private transient Object[] elementData;//ArrayLis内部存储元素的数组private int size;//数组中包含的元素的大小
构造方法:
public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; } public ArrayList() { super(); this.elementData = EMPTY_ELEMENTDATA; } public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); size = elementData.length; if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); }可以看到默认的构造方法,其实是创建了一个长度为0的数组(EMPTY_ELEMENTDATA={}),具体扩容操作是在add的时候
而指定大小的就根据大小初始化对应大小的数组
第三个构造方法就是将传进来的集合的元素数组转换为数组初始化elementData,大小赋值给size
add方法:
public boolean add(E e) { ensureCapacityInternal(size + 1); elementData[size++] = e; return true;}private void ensureCapacityInternal(int minCapacity) { if (elementData == EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity);}private void ensureExplicitCapacity(int minCapacity) { modCount++;//这个变量参考hashMap //当add的时候,会判断 加入后 的大小是否大于数组长度,若超过就扩容 if (minCapacity - elementData.length > 0) grow(minCapacity);}private void grow(int minCapacity) { int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1);//大小为原来的两倍 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // 将旧数组的元素放到新数组中 elementData = Arrays.copyOf(elementData, newCapacity);}前面都是一堆判断,最核心的还是grow操作,这是数组进行扩容的地方,大小变为原来的两倍
所以在使用集合的时候需要考虑数据的大小,如果知道数据的大概范围可以先指定数组的大小,否则太小会进行扩容,性能显然是会有影响的
remove方法:
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; return oldValue; }逻辑很简单,先取出该位置上的值,然后就是移除了数组中的一个元素后,需要将该位置以后的元素往前移动一个位置
addAll方法:
public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; }addAll方法也很简单主要是下面几步:
1.将集合c转换成数组a
2.进行扩容
3.将数组a的元素放到elementData上
4.size增加
好吧,主要的方法就这几个,其他不是很难就不说了
0 0
- 集合源码分析----ArrayList
- Java集合-ArrayList源码分析
- 【java集合】ArrayList源码分析
- java 集合ArrayList及LinkList源码分析
- 集合框架之ArrayList源码分析
- Java集合框架源码分析之ArrayList
- java 集合ArrayList及LinkList源码分析
- 从源码分析java集合【ArrayList】
- Java集合系列之ArrayList源码分析
- 集合类学习之Arraylist 源码分析
- java 集合ArrayList及LinkList源码分析
- 集合类学习之Arraylist 源码分析
- java集合03--ArrayList源码分析
- java集合03--ArrayList源码分析
- Java集合源码分析之ArrayList
- java 集合ArrayList及LinkList源码分析
- java集合类源码分析 ArrayList
- Java集合-ArrayList源码分析及注意事项
- Linux中cp命令介绍
- js中Window跟window的区别
- NODEMCU调试心得3 - 关于nodemcu的点点滴滴
- Codeforces Round #379 (Div. 2) C. Anton and Making Potions
- 有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数。
- 集合源码分析----ArrayList
- C#命名规范
- 并查集-hdu1232
- 利用minAreaRect计算平面矩形的旋转角度
- 折半插入
- FlycoRoundView 自定义TextView
- where子句的简单实用
- Android应用开发SharedPreferences存储数据的使用方法
- android dataBinding详解