JAVA List删除时需注意的地方
JAVA的LIST在删除时,一般会用list.remove(o); 但这样往往会出现问题,先来看下面的这段代码:
package com.demo; import java.util.ArrayList;
import java.util.List; public class Test11 { public void delete(){
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(2);
list.add(3);
for (int i = 0; i < list.size(); i++) {
if(list.get(i)==2){
list.remove(i);
}
}
this.outputList(list);
} private void outputList(List<Integer> list){
for (Integer i : list) {
System.out.println(i);
}
} public static void main(String[] args) {
Test11 t = new Test11();
t.delete(); } }
返回结果是:
1
2
3
这结果显然不是我们的预期,我们是希望删除List中所有为2的元素,但输出结果中却出现了2,这是因为在i等于1时,删除了List中的index为1的元素2,这时候list为[1,2,3], 但接下来,i递增后,等于2,在list.get(i)时,取出来的结果就成为了3了,也就是说随着list元素的删除,index是随之变化的,这就是其中的陷阱,于是,我们得寻找一个在删除时,索引不发生变化的迭代方式来删除,而iterator是被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,也就是用cursor来维护这个索引表,于是,可以这样来删除:
package com.demo; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class Test11 { public void delete(){
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(2);
list.add(3);
this.iteratorDelete(list.iterator(), 2);
this.outputList(list);
} private void iteratorDelete(Iterator<Integer> it, int deleteObject){
while(it.hasNext()){
int i = it.next();
if(i==deleteObject){
it.remove();
}
}
} private void outputList(List<Integer> list){
for (Integer i : list) {
System.out.println(i);
}
} public static void main(String[] args) {
Test11 t = new Test11();
t.delete(); } }
这个代码结果就是正确的了!
可能有人会说,我是在iterator中删除的,为什么list的值会发生改变?这个问题,自已思考去吧!思考不出来,可以转行了!
JAVA List删除时需注意的地方的更多相关文章
- Java编程提高性能时需注意的地方
1.尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面 第一,控制资源的使用,通过线程同步来控制资 ...
- <2014 05 09> 程序员:从C++转到Java需注意的地方
最近想玩玩Android的APP开发,从C++角度来学习Java.Java可以说是一个优化精简版的C++,去除了底层C的很多特性.找了这篇文章. --------------------------- ...
- Web API核查表:设计、测试、发布API时需思考的43件事[转]
Web API核查表:设计.测试.发布API时需思考的43件事 当设计.测试或发布一个新的Web API时,你是在一个原有的复杂系统上构建新的系统.那么至少,你也要建立在HTTP上,而HTTP则是 ...
- 《深入理解Java虚拟机》(二)Java虚拟机运行时数据区
Java虚拟机运行时数据区 详解 2.1 概述 本文参考的是周志明的 <深入理解Java虚拟机>第二章 ,为了整理思路,简单记录一下,方便后期查阅. 2.2 运行时数据区域 Java虚拟机 ...
- 使用SQL Server 2014内存数据库时需要注意的地方
作者 王枫发布于2014年7月4日 本文从产品设计和架构角度分享了Microsoft内存数据库方面的使用经验,希望你在阅读本文之后能够了解这些新的对象.概念,从而更好地设计你的架构. 内存数据库,指的 ...
- 基于 Java 2 运行时安全模型的线程协作--转
在 Java 2 之前的版本,运行时的安全模型使用非常严格受限的沙箱模型(Sandbox).读者应该熟悉,Java 不受信的 Applet 代码就是基于这个严格受限的沙箱模型来提供运行时的安全检查.沙 ...
- Java虚拟机运行时栈帧结构--《深入理解Java虚拟机》学习笔记及个人理解(二)
Java虚拟机运行时栈帧结构(周志明书上P237页) 栈帧是什么? 栈帧是一种数据结构,用于虚拟机进行方法的调用和执行. 栈帧是虚拟机栈的栈元素,也就是入栈和出栈的一个单元. 2018.1.2更新(在 ...
- java项目启动时执行指定方法
想到的就是监听步骤如下: 1.配置web.xml <listener> <listener-class>com.listener.InitListener</listen ...
- Spring Shell打Jar包时需要注意的地方
Spring-Shell打Jar包时需要注意的地方: 1.Main-Class spring-shell项目打Jar包的一个必要条件就是,指定Main-Class为org.springframew ...
随机推荐
- easyui权限系统改造备忘
修改list.js文件 //// 如果所有操作按钮隐藏,则list-toolbar隐藏 //if ($(".list-toolbar").length > 0) { // v ...
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十)安装hadoop2.9.0搭建HA
如何搭建配置centos虚拟机请参考<Kafka:ZK+Kafka+Spark Streaming集群环境搭建(一)VMW安装四台CentOS,并实现本机与它们能交互,虚拟机内部实现可以上网.& ...
- linux命令大全网站
一. linux命令大全网站 http://man.linuxde.net/watch
- 如何获取当前应用程序所用的OpenGL ES的版本
如何获取当前应用程序所用的OpenGL ES的版本? [答案] char* glVersion = (char*)glGetString(GL_VERSION); LOGW(&qu ...
- Hdfs dfs命令使用
如果是把数据放在了hdfs系统,那么我们如何访问他们呢? 1.hdfs查看文件夹 ./hdfs dfs -ls hdfs://mycluster/output/online/ 2.hdfs创建目录df ...
- Wifidog的协议梳理
上篇文章结合wifidog的协议,讲解了如何实现wifi认证.这篇文章会详细讲解一下wifidog的协议. wifidog的认证流程图 用户连接WIFI会跳转到以下地址: 1 2 3 4 5 6 7 ...
- python数据结构与算法 29-1 哈希查找
).称为哈希查找. 要做到这种性能,我们要知道元素的可能位置.假设每一个元素就在他应该在的位置上,那么要查找的时候仅仅须要一次比較得到有没有的答案,但以下将会看到.不是这么回事. 到10. water ...
- C#.NET常见问题(FAQ)-命名空间namespace如何理解
Namespace就是定义一个对象是哪个门派的,比如你现在就在A门派下,A门派的所有功夫(属性和方法)都可以不加声明直接调用.如果你要用B门派的功夫,就要先声明是B门派的XXX对象的XXX实例的XXX ...
- 坑人无数的Redis面试题
https://baijiahao.baidu.com/s?id=1588454565071211950&wfr=spider&for=pc 坑人无数的Redis面试题
- IO multiplexing 与 非阻塞网络编程
使用I/O multipexing 的网络编程中,一般需要采用非阻塞网络编程的风格,防止服务端在处理高连接量大时候阻塞在某个文件描述符上面,比如某个socket 有大量的数据需要写,但是内核发送缓冲区 ...