Java集合-ArrayListy(二)
来源:互联网 发布:苏联的秘密武器知乎 编辑:程序博客网 时间:2024/06/07 14:22
ArrayList源码解析
主要方法
删除元素
1
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; // clear to let GC do its work return oldValue; }
2
public boolean remove(Object o) { //for循环遍历去删除指定元素,相同元素删除下标小的 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; }
3从该列表中移除包含在指定集合中的所有元素。
public boolean removeAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, false);
4仅保留包含在指定集合中的此列表中的元素。换句话说,从该列表中移除所有未包含在指定集合中的元素。
public boolean retainAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, true); }
5removeAll和retainAll区别在于batchRemove(a,b)的第二个参数
private boolean batchRemove(Collection<?> c, boolean complement) { final Object[] elementData = this.elementData; int r = 0, w = 0; boolean modified = false; try { for (; r < size; r++) /* 如果complement为false,将c中不包含的ArrayList的元素放在一个elementData[]数组中,完成删除;如果complement为true,反之。 */ if (c.contains(elementData[r]) == complement) elementData[w++] = elementData[r]; } finally { // 保存和收集的行为兼容性, / /即使C. contains()抛出。 if (r != size) { System.arraycopy(elementData, r, elementData, w, size - r); w += size - r; } if (w != size) { // clear to let GC do its work for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w; size = w; modified = true; } } return modified; }
遍历ArrayList的方法
for(Object o:list)for(int i=0;i<=list.size();i++)Iterator<String> i = list.iterator();while(i.hasNext())
问题:遍历的时候去删除元素,会出现什么问题?
List<String> list = new ArrayList(); list.add("1"); list.add("2"); list.add("3"); list.add("4"); list.add(1, "6"); list.remove("11"); for(String i:list){ list.remove(i); } for(int i=0;i<=list.size();i++){ list.remove(i); } System.out.println(list.isEmpty()); Iterator<String> i = list.iterator(); while(i.hasNext()){ i.remove(); }
foreach会抛ConcurrentModificationException
for循环却是删除不完元素
使用iterator则没有问题
foreach在循环遍历时,底层也是 private class Itr implements Iterator这个内部类的方法。
private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { //foreach循环时,删除完元素的下一次遍历在这里抛异常是因为modCount和expectedModCount 的大小不一样了,(内部类无法同步外部变量) checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
for循环在删除时,size的大小随着每次删除完,大小在变化,所以没法删除完全。
有问题欢迎提出。
阅读全文
1 0
- Java集合-ArrayListy(二)
- java集合(二)
- Java集合(二)
- Java集合(二)
- JAVA---------集合(二)
- Java集合概述(二):List集合
- Java集合(二)List集合
- Java集合简述(二)
- Java集合总结(二)
- JAVA集合类型(二)
- java-集合类(二)
- JAVA集合(二)-ArrayList
- Java集合详解(二)
- JAVA 集合(二)--collection
- Java集合框架(二)
- Java集合总结(二)
- java集合框架(二)
- Java再学习-java集合(二)
- 引用类型参数的传值
- Javascript
- 三级级联菜单
- 虽然不简单但还是要学的JavaWeb—Spring_IOC
- 使用ssh公钥实现免密码登录 (2011-04-22 01:24:10)
- Java集合-ArrayListy(二)
- 环境搭建之window下solr配置
- Recommend《黑客与画家》
- 广义线性模型
- 记录下一年多搞ACM的时光
- HDOJ5584 Lcm Walk 2015ICPC上海-L
- HDU 5185 Equation 完全背包变形.
- Faster RCNN详解
- 【宏观】两期动态模型