Java循环删除集合多个元素的正确打开方式
首先说下不正确的打开方式:
第一:使用for循环删除集合的元素,示例代码如下
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (int i = 0; i < list.size(); i++) {
list.remove(i);
}
System.out.println(list);
结果输出为:
[b, d]
解说开始:
首先看下源码:
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;
}
解释:第一次进for循环,i=0 ,调用remove方法删除第一位的元素, 集合大小收缩,第一次删除完成后,list变成【b,c,d】;再次循环,i=1,调用remove方法删除了c 集合大小再次收缩,list变成【b,d】;再次循环,i=2,不符合条件,循环结束
第二:使用foreach循环删除元素,示例代码如下
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (String s : list) {
if (s.equals("b"))
list.remove(s);
}
System.out.println(list);
结果:这段代码居然抛出了异常 java.util.ConcurrentModificationException。
解说开始:
首先看下源代码:
public Iterator<E> iterator() {
return new Itr();
}
/**
* 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();
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();
}
}
解释:在Java中的foreach循环的工作原理就像一个iterator。
so,接下来说下正确的打开方式——
ArrayList<Integer> a=new ArrayList<Integer>(15);
a.add(222);
a.add(3);
a.add(333);
a.add(000);
a.add(333);
a.add(4); for(int s=a.size()-1;s>=0;s--){
if(a.get(s).intValue()==333){
a.remove(s);
}
}
privatevoid screenBlackNameList(List<SharedBoardSmsWrapper> source, List<BlackNameListModel> blackNameList){
Iterator<SharedBoardSmsWrapper> sourceIt=source.iterator();
while(sourceIt.hasNext()){
SharedBoardSmsWrapper tmpSharedBoardSmsWrapper=sourceIt.next();
Iterator<BlackNameListModel> blackNameListIt=blackNameList.iterator();
while(blackNameListIt.hasNext()){
BlackNameListModel tmpBlackNameListModel=blackNameListIt.next();
if(tmpSharedBoardSmsWrapper.getSource().equals(tmpBlackNameListModel.getSource())){
sourceIt.remove();
break;
}
}
}
}
Java循环删除集合多个元素的正确打开方式的更多相关文章
- (CSDN 迁移) JAVA循环删除List的某个元素
若列表中只可能存在一个则可以用简单的循环删除,不多说. 若列表中可能存在多个,尤其是可能有多个连续的需要删除,用简单循环有可能发生异常. 需要使用迭代器(Iterator),两种具体实现: 逻辑上是一 ...
- for循环删除集合陷阱
首先看下面的代码: import java.util.LinkedList;import java.util.List; public class DeleteCollection { ...
- 集合赋值及for循环删除符合条件的元素
一.Java语言中ArrayList对象能直接赋值给另一个ArrayList对象吗? https://zhidao.baidu.com/question/399214655.html ArrayLis ...
- ArrayList之foreach循环删除倒数第二个元素,不触发fail-fast机制
今天一朋友问了个问题,对于如下一段代码,运行后会有怎样的结果? public class ArrayListTest { public static void main(String[] args) ...
- Python笔记:用for循环删除列表中的元素
for运行过程中会有一个指针来记录当前循环的元素是哪一个,一开始这个指针指向第0个元素,然后获取它,接着删除第0个元素,这时候,原来是第1个的元素会变成第0个,当指针向后移动一次,指向了现在第1个元素 ...
- python循环删除list中的元素
直接上例子: a = [1,2,3,4,5,6] for i in a: a.remove(i) print(a) 返回:[2, 4, 6] 循环a,想删除a的所有元素,但实际确有数据保留了下来,这是 ...
- Java思考——HashSet集合如何保证元素的唯一性也就是不包含重复元素?
首先将源码逐级找出来1.HashSet<String> hs=new HashSet<String>(); hs.add("hello"); ...
- C#实现在foreach中删除集合中的元素
List<string> str = new List<string>(); str.Add( "zs"); str.Add("ls") ...
- java的取出map里所有元素的两种方式
/* * 取出map元素的两种方式 */package com.map.test; import java.util.HashMap;import java.util.Iterator;import ...
随机推荐
- ML-分类与逻辑回归
布尔分类(binary classification)问题: 训练集:$S=\{(x^{(i)}, y^{(i)})\}$ 输入:特征向量$x$ 期望输出:$y\in\{0, 1\}$ 这里使用的假设 ...
- CentOS 安装 Dubbo 管理控制台
安装之前需要安装zookeeper详情http://www.cnblogs.com/zuge/p/6141101.html Dubbo 管控台可以对注册到 zookeeper 注册中心的服务或服务消费 ...
- 对一个二维数组进行升序排列a[0][1]为最小
public static int[][] dyadicArraySort(int a[][]){ int temp=0;int sum =0;int nn=0; for(int i=0;i<a ...
- nginx安装方式
1.首先安装pcre库 获取pcre到一个目录 wget http://ftp.exim.llorien.org/pcre/pcre-8.21.tar.gz 解压缩pcre包 tar -zxvf pc ...
- C++ STL之vector用法总结
介绍 vector是表示可变大小数组的序列容器. 就像数组一样,vector也采用的连续存储空间来存储元素.也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效.但是又不像数组,它的大 ...
- Log4net(1):配置的简单说明
基础代码下载地址:https://github.com/zhangsai521314/StudyLog4net 1:按日期分隔日志 <configSections> <section ...
- Express+mysql的博客(1)
学了东西一定要自己上手试过才知道是不是真的会了.一直想练练node的使用,本来也没有什么好想法的,经同学提醒了一下,发现其实我可以用node写一个博客.我同学说工作量会非常之大╮(╯_╰)╭那也得先试 ...
- jQuery.eq() 函数
eq() 函数 获取当前对象中指定索引所对应的的元素 语法 $selector.eq(index)//index为指定索引,值为数字型 返回值 返回值为一个对象 实例说明 代码 <!DOCTYP ...
- iOS - PackIpa App 打包
前言 打包 ipa 的前提 证书的申请和设置和 "App 上架" 文章的一样 从第一步到第四步都是一样的.还有第六步的 1-3 都是一样的,从第四步开始变化. 1.Archive ...
- mysql存储过程语法及实例
存储过程如同一门程序设计语言,同样包含了数据类型.流程控制.输入和输出和它自己的函数库. --------------------基本语法-------------------- 一.创建存储过程cr ...