- 浏览: 211262 次
- 性别:
- 来自: 哈尔滨
文章分类
- 全部博客 (267)
- java.lang (8)
- 问题汇总 (21)
- 异常记录 (20)
- 功能实现 (19)
- 面试总结 (25)
- 技巧总结 (8)
- 常用代码 (4)
- 编程习惯 (3)
- 编码规则 (3)
- java.util (10)
- java.io (1)
- JavaWeb (9)
- MySQL (16)
- SVN (3)
- MyBatis (11)
- Velocity (7)
- 其他知识 (10)
- 人生哲理 (1)
- 人生故事 (1)
- 自我感悟 (1)
- shiro (3)
- 基础知识 (0)
- 问题总结 (1)
- Spring 标签 (1)
- Spring (3)
- 点滴生活 (1)
- DOS (1)
- CAS (4)
- Linux (9)
- Storm (6)
- Shell (1)
- regex (1)
- Collection (4)
- poi (1)
- 经典语句 (1)
- NIO (5)
- concurrent (14)
- RPC (1)
- zookeeper (3)
- 待整理 (2)
- Hadoop (9)
- RabbitMq (2)
- flume (1)
- hive (7)
- hbase (4)
- kafka (1)
- scala (1)
- GC (0)
- java.util.concurrent.atomic (1)
- java.lang.ref (6)
- JVM (2)
- algorithm (1)
- conception (1)
- java key word (1)
- sun.misc (1)
最新评论
一、根据下标删除元素
1.测试代码
2.实现原理
3.其他情况
删除单个元素,可以使用此方式,但多个元素的情况下不可以
因为删除一个元素后,数组的大小以及原来元素的下标都会改变;需要做相应的处理才可。
二、foreach
1.代码实现
运行抛出异常
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
2.异常分析
从定位的异常信息看遍历的过程中进行了 chcek
modCount 实际对数组进行操作的次数,expectedModCount 预期操作次数
初始化
但在遍历的同时,执行了remove操作,导致了 modCount+1 ,与 expectedModCount 不一致
3.为什么删除元素的方法会调用 Next
java foreach 实现原理
中 foreach 实质就是Iterator 的调用实现
删除元素的实现过程
即可以认为调用了 ArrayList 的 Iterator 方法,返回了 其内部实现的静态类 Itr
在foreach 的过程中,即 Iterator 的 next 操作的过程中 每次获取下一个元素前都会进行一次校验
抛出不允许同时进行修改操作的异常
三、Iterator
将集合转为Iterator 通过 Iterator 来进行集合删除的操作。
1.测试代码
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for(int index = 0 ; index < list.size() ; index++){ if(Objects.equals("a", list.get(index))){ list.remove(index); } } System.out.println(String.valueOf(list));
2.实现原理
/** * Removes the element at the specified position in this list. * Shifts any subsequent elements to the left (subtracts one from their * indices). * * @param index the index of the element to be removed * @return the element that was removed from the list * @throws IndexOutOfBoundsException {@inheritDoc} */ // 在列表中指定位置删除元素。 // 所有后续元素左移(下标减1)。 public E remove(int index) { rangeCheck(index); // 是否越界,index 是否大于了 数组的长度 modCount++; // 操作次数 E oldValue = elementData(index); int numMoved = size - index - 1; // 将index+1后numMoved个元素拷贝到index的位置上 // 覆盖index位置上的元素,多出的一个位置设置为null,等待GC if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; }
3.其他情况
删除单个元素,可以使用此方式,但多个元素的情况下不可以
因为删除一个元素后,数组的大小以及原来元素的下标都会改变;需要做相应的处理才可。
ArrayList<String> list1 = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for(int index = 0 ; index < list1.size() ; index++){ // 删除 index = 0 即 a 元素后,数组大小变为3,b的下标变为0,所以再次删除的是c,最后退出循环 list1.remove(index); } System.out.println(String.valueOf(list1));
二、foreach
1.代码实现
for (String s : list) { if (s.equals("a")) list.remove(s); }
运行抛出异常
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
2.异常分析
// 异常抛出的位置 final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } /** * An optimized version of AbstractList.Itr */ 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() { checkForComodification();// 对应的831行代码 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]; } }
从定位的异常信息看遍历的过程中进行了 chcek
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
modCount 实际对数组进行操作的次数,expectedModCount 预期操作次数
初始化
int expectedModCount = modCount;
但在遍历的同时,执行了remove操作,导致了 modCount+1 ,与 expectedModCount 不一致
3.为什么删除元素的方法会调用 Next
java foreach 实现原理
中 foreach 实质就是Iterator 的调用实现
/** * Returns an iterator over the elements in this list in proper sequence. * * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>. * * @return an iterator over the elements in this list in proper sequence */ public Iterator<E> iterator() { return new Itr(); } /** * An optimized version of AbstractList.Itr */ private class Itr implements Iterator<E> {}
删除元素的实现过程
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; }
即可以认为调用了 ArrayList 的 Iterator 方法,返回了 其内部实现的静态类 Itr
在foreach 的过程中,即 Iterator 的 next 操作的过程中 每次获取下一个元素前都会进行一次校验
抛出不允许同时进行修改操作的异常
三、Iterator
Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ if(StringUtils.isNotEmpty(iterator.next())){ iterator.remove(); } }
将集合转为Iterator 通过 Iterator 来进行集合删除的操作。
发表评论
-
使用软引用构建敏感数据的缓存
2017-11-16 22:19 845使用软引用构建敏感数 ... -
JSP自定义标签
2017-11-14 20:35 348JSP页面中分页功能实现使用了 <urlChange ... -
手机号码替换中间四位
2017-10-24 21:41 929需求描述: 为用户隐私考虑,展示用户信息时需要将中间用*代替 ... -
统计每天的数据
2017-10-10 21:23 551需求:按天统计数据 分析:create_time 为 dat ... -
基于AbstractDataSource实现主从数据库切换
2017-10-07 18:03 1054基于AbstractDataSource实现主从数据库切换 ... -
服务器文件下载
2016-03-27 09:53 384项目需求:在列表页面上提供文件下载链接 项目实现: 1.准 ... -
扫码登录功能实现
2015-08-21 08:19 522需求:PC端(电脑端) ... -
基于SHIRO实现用户登陆后跳转其匿名访问的URL路径
2015-07-15 15:03 3652需求描述: 用户在未登录时访问网站中某个需要登录后才能访问 ... -
基于SHIRO的管理后台权限认证系统实现(一)
2015-07-09 10:05 7012基于SHIRO的管理后台权限认证系统实现(一) 一、项目需求 ... -
基于SHIRO的管理后台权限认证系统实现(二)
2015-06-28 10:14 822用户登陆系统后左侧菜单加载 项目:管理员系统 功能:用户登 ... -
Velocity中set的使用
2015-05-26 10:46 536问题:从页面接收某字段的提交数据,数据要求是组合后的编号 ... -
Velocity页面中输出时间年月
2015-05-19 20:52 1010问题:注册页面要求有创建时间的选项添加,年为至今为止 实现: ... -
Set判重操作实现
2015-05-15 15:28 805需求:Set<Po>判重操作实现 问题:Set& ... -
如何去除List集合中的重复数据
2015-05-15 13:12 920需求:用户权限查看, ... -
Date相关功能实现
2015-05-12 19:47 633一、同一天 需求:用户记录跟踪列表展示,要求用户数据同一天内 ... -
velocity截取过长的字段值
2015-05-11 20:06 382问题:页面列表展示时,某个字段的值超长,影响页面的整体样式 ... -
将list中某个元素放在首位
2015-05-10 17:25 4584需求:程序开发过程中,业务方要求在展示国家列表时要将US放在首 ... -
Velocity遍历map与遍历list
2015-04-22 20:16 6949问题: 向页面传递key与value的组合 1. 1.1 ...
相关推荐
当我们需要遍历List并根据条件删除特定元素时,需要注意正确的方法,以避免在遍历过程中出现错误。以下将详细介绍如何在C#中遍历List并删除元素,包括正序和倒序遍历的技巧。 首先,我们来看一下错误的遍历方式。...
使用 Iterator 接口遍历集合元素 Java 集合框架中的 Iterator 接口是一种非常重要的接口,它主要用于遍历集合中的元素。Iterator 接口隐藏了各种 Collection 实现类的底层细节,向应用程序提供了遍历 Collection ...
在foreach中删除元素时,每一次删除都会导致集合的大小和元素索引值发生变化,从而导致在foreach中删除元素时会抛出异常。 集合已修改;可能无法执行枚举操作。 方法一:采用for循环,并且从尾到头遍历 如果...
迭代器模式是一种行为设计模式,主要目的是在不暴露集合内部结构的情况下,允许外部代码遍历集合的所有元素。这种模式将遍历操作从集合类中分离出来,实现了数据结构和遍历机制的解耦。在大多数编程语言中,迭代器...
在Java编程语言中,`foreach`循环是一种简洁的遍历集合元素的方式,它引入自Java 5(JDK 1.5)。`foreach`循环也被称为增强for循环,它的主要目的是简化对数组和集合的迭代操作。在本实例中,我们将深入探讨如何使用...
总的来说,迭代器模式在遍历集合时提供了一种优雅的方式,但同时也要求我们在遍历过程中谨慎处理对集合的修改。正确使用迭代器提供的方法,如`Iterator.remove()`,可以确保遍历的正确性和一致性。同时,了解不同...
在C#编程中,遍历集合和移除元素是常见的操作,尤其在处理大量数据时。本篇文章将详细讲解如何使用C#有效地遍历集合并安全地移除元素,同时提供一些最佳实践。 首先,我们要了解C#中的两种主要遍历集合的方式:`for...
在Java编程中,遍历并删除集合(如List或Set)中的元素是一项常见的操作,但如果不正确地执行,可能会...在遍历集合时,始终优先考虑使用Iterator或Java 8以上的特性,以避免`ConcurrentModificationException`异常。
本文将深入分析Java中三种主要的遍历集合方法:传统的for循环遍历、迭代器遍历以及foreach循环遍历。 1. **传统的for循环遍历**: 这种方式依赖于计数器,开发者需要手动初始化并维护计数器,依次读取集合中的每个...
1. 操作DOM:遍历DOM可以方便地查找特定节点,添加、删除或修改元素。 2. 渲染动画:遍历DOM可以实现复杂的动画效果,比如逐个改变元素样式。 3. 数据绑定:在MVVM框架中,遍历DOM用于将数据绑定到视图。 4. 事件...
本文将详细介绍Java中遍历集合的三种常见方式,并通过实例进行对比分析。 ### 方式一:转化为数组后遍历 这种方式首先将集合(如List)转化为数组,然后通过数组的for-each循环进行遍历。代码如下: ```java ...
HashMap和List遍历方法及如何遍历删除元素总结 HashMap和List都是Java中最常用的数据结构,它们都可以用来存储和操作数据。然而,在遍历和删除元素时,需要小心地处理,以免出现问题。下面总结了HashMap和List的...
当我们需要在遍历集合的过程中删除或添加元素时,必须注意一些特定的策略,因为不是所有的集合类型都支持这种操作。这里我们将详细讨论如何在C#中处理这种情况,特别是在使用`LinkedList<T>`时。 首先,C#的标准...
接下来,我们将深入探讨这两个接口,以及它们在遍历集合时的差异和应用场景。 首先,`Enumeration` 是早期Java版本(JDK 1.0)中引入的接口,主要用于遍历 `Vector`、`Hashtable` 等旧版集合类。`Enumeration` 提供...
当你在一个迭代器正在遍历集合的过程中添加或删除元素时,就会抛出这个异常。这个问题在单线程环境下不会出现,但在多线程并发场景下,如果多个线程同时修改一个集合,就可能导致`ConcurrentModificationException`...
在Java中,常见的遍历集合的方法包括传统的for循环、迭代器Iterator以及foreach循环。 1. 传统的for循环遍历 这种方式需要开发者手动维护一个计数器,并通过调用`size()`方法获取集合长度,然后通过`get(index)`...
Java中的List接口定义了iterator()方法,返回一个Iterator对象,用于遍历集合。使用迭代器的优点是可以安全地删除集合中的元素,而不会影响到其他元素的索引。 ```java List<String> list = new ArrayList(); // ...
- **推荐**:使用Iterator是安全的遍历和删除元素的方法,因为它允许在遍历过程中修改底层集合。 - **示例**: ```java Iterator<Student> stuIter = students.iterator(); while (stuIter.hasNext()) { ...