愚公移山----ArrayList(增、删操作),虽然这些博文在网络上有很多,但是我觉得还是要经过自己写一遍之后,才能更好的沉淀下来。
1、新建ArrayList
List<String> list = new ArrayList<String>(); if(log.isDebugEnabled()){ log.debug("ArrayList初始化长度:"+list.size()); }
ArrayList在new的时候,如果不指定大小,默认会Constructs an empty list with the specified initial capacity,这个specified initial capacity是10。在JDK源码中可以看到这部分代码
public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = (E[])new Object[initialCapacity]; }
身旁的同事都建议,在初始化一个ArrayList的时候,最好吧initial_capacity传进去。
2、添加元素
最常用的方法是add(Object)
public boolean add(E o) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = o; return true; }
这个方法中的关键一步是ensureCapacity(),看源码来分析吧
public void ensureCapacity(int minCapacity) { // 这个modCount是ArrayList的一个小灵魂,记录ArrayList被操作的次数 modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; //容量计算方法 (size*3)/2 + 1 if (newCapacity < minCapacity) newCapacity = minCapacity; elementData = (E[])new Object[newCapacity]; System.arraycopy(oldData, 0, elementData, 0, size); //元素拷贝 } }
需要关注的地方有三处:modCount 、int newCapacity=(oldCapacity*3)/2+1;、System.arraycopy(oldData,0,elementData,0,size);
3、移除元素
3.1 remove(index) 根据下标移除元素
public E remove(int index) { RangeCheck(index); //Check if the given index is in range modCount++; E oldValue = 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; //返回被移除的元素,这个地方返回之后,该元素在ArrayList中就找不到了 }
检查下标合法的方法RangeCheck(index)
private void RangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); }
删除操作1:
for (int i = 0, j = list.size(); i < j; i++) { if ("obj-1".equals(list.get(i))) { list.remove(i); } }
这个代码在做删除的时候会报数组越界,虽然这个时候ArrayList的容量不止这么多,但是在get的时候,回去做一次下标判断,如果大于或等于arrayList的size就会报错了,size和capacity是两个不同的概念。
删除操作2:
for (int i = 0; i < list.size(); i++) { if ("obj-1".equals(list.get(i))) { list.remove(i); } }
这个代码是不会出错的,但是如果for循环里做了多次remove操作是有安全隐患的。
推荐的移除操作:
//使用迭代器做移除操作是最好的选择 Iterator<String> iterator = list.iterator(); while (iterator.hasNext()){ if("ojb-1".equals(iterator.next())){ iterator.remove(); } }