ArrayList源码分析
来源:互联网 发布:lol老是网络断开连接 编辑:程序博客网 时间:2024/06/06 13:06
List:
ArrayList:底层数组实现,线程不安全(不要觉得不安全就觉得不好),效率高。增删改查中查询快,其余比较慢
LinkedList:底层链表实现,线程不安全,效率高。增删改查中查询慢,其余都快
- Vector:线程安全,但是效率低
ArrayList:
1.成员变量:
- private static final long serialVersionUID = 8683452581122892189L
- private transient Object[] elementData;
- private int size;
说明:
serialVersionUID :和序列化有关,等了解完序列化后在补充。
elementData:实际存对象的数组
size:当前存放的对象的数量(不用说也是小于等于elementData的申请长度的)
transientjava语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。换句话来说就是,用transient关键字标记的成员变量不参与序列化过程。
方法:
public
2.扩容函数(ensureCapacity)
public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; //可以看到每次扩充1.5倍 if (newCapacity < minCapacity) newCapacity = minCapacity; //扩容后如果还小那就直接扩到需要的大小。 // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } }
关于modCound
3.size
public int size() { return size; }
4.isEmpty
public boolean isEmpty() { return size == 0; }
5.contains(是否包含对象o)
public boolean contains(Object o) { return indexOf(o) >= 0; //indexOf(o)若对象o在该ArrayList中存在,返回下标,否则返回-1,下一个就是。 }
6.indexOf()
public int indexOf(Object o) { if (o == null) { //可以看到允许往ArrayList存入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中放入了多个相同的对象,那么只会返回最先找到的下标
7.lastIndexOf() //从后往前找
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; }
8.clone :返回此 ArrayList 实例的浅表复制。(不复制这些元素本身。)
注意这是从Object重写过来的方法,所以用List多态时点不出来clone
public Object clone() { try { ArrayList<E> v = (ArrayList<E>) 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(); } }
9.toArray() :就是将elementData给提取出来
public Object[] toArray() { return Arrays.copyOf(elementData, size); }
10.toArray(T[] a)
public <T> T[] toArray(T[] a) { if (a.length < size) //如果给的数组放不下那就尽量放 // Make a new array of a's runtime type, but my contents: return (T[]) Arrays.copyOf(elementData, size, a.getClass()); System.arraycopy(elementData, 0, a, 0, size); if (a.length > size) //如果指定的数组能容纳列表并有剩余空间(即数组的元素比列表的多),那么会将数组中紧跟在集合末尾的元素设置为 null。这对确定列表的长度很有用,但只 在调用方知道列表中不包含任何 null 元素时才有用。 a[size] = null; return a; }
11.get():返回指定下表的元素
public E get(int index) { RangeCheck(index); return (E) elementData[index]; }
12.set():修改给定下表的值
public E set(int index, E element) { RangeCheck(index); E oldValue = (E) elementData[index]; elementData[index] = element; return oldValue; }
13.add(E e):给末尾添加e
public boolean add(E e) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
14.add(int index, E element):给指定位置添加
public void add(int index, E element) { if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); ensureCapacity(size+1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; }
arraycopy
public static void arraycopy(Object src,
int srcPos,
Object dest,
int destPos,
int length)从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。从 src 引用的源数组到 dest 引用的目标数组,数组组件的一个子序列被复制下来。被复制的组件的编号等于 length 参数。源数组中位置在 srcPos 到 srcPos+length-1 之间的组件被分别复制到目标数组中的 destPos 到 destPos+length-1 位置。
- remove(int index)
public E remove(int index) { RangeCheck(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; // Let gc do its work return oldValue; }
16.remove(Object o)
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; }
17.fastRemove(int index)
private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc do its work }
18.clear()
public void clear() { modCount++; // Let gc do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; }
19.addAll(Collection
public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacity(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; }
20.addAll(int index, Collection
public boolean addAll(int index, Collection<? extends E> c) { if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: " + index + ", Size: " + size); Object[] a = c.toArray(); int numNew = a.length; ensureCapacity(size + numNew); // Increments modCount int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved); System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; }
protected方法
21.removeRange(int fromIndex, int toIndex):将这两个位置之间的元素都remove
protected void removeRange(int fromIndex, int toIndex) { modCount++; int numMoved = size - toIndex; System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved); // Let gc do its work int newSize = size - (toIndex-fromIndex); while (size != newSize) elementData[--size] = null; }
private方法
22.writeObject(java.io.ObjectOutputStream s)
private void RangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); } private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ // Write out element count, and any hidden stuff int expectedModCount = modCount; s.defaultWriteObject(); // Write out array length s.writeInt(elementData.length); // Write out all elements in the proper order. for (int i=0; i<size; i++) s.writeObject(elementData[i]); if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } }
23.readObject(java.io.ObjectInputStream s)
private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in size, and any hidden stuff s.defaultReadObject(); // Read in array length and allocate array int arrayLength = s.readInt(); Object[] a = elementData = new Object[arrayLength]; // Read in all elements in the proper order. for (int i=0; i<size; i++) a[i] = s.readObject(); }}
2017-11-26更新:
容器类的所有父类/祖父类…..是AbstractCollection这个抽象类,这个类是直接继承了Object,而这个类中重写了Object的toString方法,用于遍历容器类.
代码:
public String toString() { Iterator<E> i = iterator(); if (! i.hasNext()) return "[]"; StringBuilder sb = new StringBuilder(); sb.append('['); for (;;) { E e = i.next(); sb.append(e == this ? "(this Collection)" : e); if (! i.hasNext()) return sb.append(']').toString(); sb.append(", "); } }
所以(ArrayList对象).toString会以数组的形式显示该容器中包含的全部对象
- ArrayList源码分析
- ArrayList源码分析
- ArrayList 源码分析
- ArrayList源码分析
- ArrayList LinkedList 源码分析
- ArrayList,LinkedList源码分析
- 源码分析之ArrayList
- ArrayList 源码分析
- ArrayList源码分析
- ArrayList源码分析
- ArrayList源码分析
- ArrayList源码分析
- ArrayList源码分析
- ArrayList 源码分析
- Java ArrayList源码分析
- ArrayList源码分析
- Java ArrayList 源码分析
- ArrayList的源码分析
- 双重while循环实现打印数字11-99
- iLnkView隐私政策
- linux用户管理
- rpath和runpath的区别
- Magento获取商品CategoryIds
- ArrayList源码分析
- CAS客户端使用Ajax登陆(即保留原有客户端登录页面)
- 单精度实型和双精度实型的有效位数
- (linux下windows下一样)mysql如何插入中文,解决插入中文报错,ERROR 1366 (HY000):Incorrect string value
- Kmeans算法
- 基于Django的微信公众号开发(3) -- 通过微信公众号开发者认证
- SSM框架-MyBatis篇
- 51nod 1205 流水线调度 贪心(写排序函数)Johnson算法
- 关于 java.lang.IllegalStateException: Fragment already added 解决方式