教程集 www.jiaochengji.com
教程集 >  脚本编程  >  java  >  正文 JAVA List使用Remove时的一些问题

JAVA List使用Remove时的一些问题

发布时间:2016-10-19   编辑:jiaochengji.com
教程集为您提供JAVA List使用Remove时的一些问题等资源,欢迎您收藏本站,我们将为您提供最新的JAVA List使用Remove时的一些问题资源
List中可以添加任何对象,包括自己定义的新的类了,本文章介绍的是JAVA List使用Remove时的一些问题的解决办法。


近日在项目中遇到了一个诡异的问题,参考代码如下:

[java]
public class ListTest {
public static List listFactory() {
return new ArrayList(Arrays.asList("a", "b", "c", "d"));
}

public static void main(String[] args) {
List testList = null;
String t;

// 尝试移除集合中的间隔元素a、c
testList = listFactory();
for (int i = 0; i < testList.size(); i ) {
t = testList.get(i);
if (t.equals("a") || t.equals("c")) {
testList.remove(t);
}
}
System.out.println("移除间隔元素a、c后结果:" testList);

// 尝试移除集合中的相邻元素a、b
testList = listFactory();
for (int i = 0; i < testList.size(); i ) {
t = testList.get(i);
if (t.equals("a") || t.equals("b")) {
testList.remove(t);
}
}
System.out.println("移除相邻元素a、b后结果:" testList);
}
}
[/java]

而运行后的结果如下:

[java]
移除间隔元素a、c后结果:[b, d]
移除相邻元素a、b后结果:[b, c, d]
[/java]

从运行的结果来看,在操作List时使用remove方法在移除间隔元素成功,而移除相邻元素时会导致漏删除。

失败原因
通过查看remove()的源码后发现,List内实现remove是通过如下方法实现的。

[java]
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;
}

private void fastRemove(int index) {
modCount ;
int numMoved = size – index – 1;
if (numMoved > 0)
System.arraycopy(elementData, index 1, elementData, index,
numMoved);
elementData[–size] = null; // Let gc do its work
}
[/java]

fastRemove方法是实现的关键,从实现上来看,他是将要删除的元素后的元素逐一向前挪一位来实现的。我们在循环删除时若外层当前的index为1,将之删除,后续元素往前挪,然后外层的index加1继续循环,这样会导致被删除元素的后面紧邻元素不会被遍历到,从而导致漏删。

解决办法
使用逆序删除的办法[java]
public class ListTest {
public static List listFactory() {
return new ArrayList(Arrays.asList("a", "b", "c", "d"));
}
public static void main(String[] args) {
List testList = null;
String t;

// 逆序移除相邻元素a、b后
testList = listFactory();
int size = testList.size();
for (int i = size – 1; i >= 0; i–) {
t = testList.get(i);
if (t.equals("a") || t.equals("b")) {
testList.remove(t);
}
}
System.out.println("逆序移除相邻元素a、b后结果:" testList);
}
}
[/java]

使用iterator删除[java]
public class ListTest {
public static List<String> listFactory() {
return new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
}
public static void main(String[] args) {
List<String> testList = null;
String t;

// 使用iterator移除相邻元素a、b后
testList = listFactory();
Iterator<String> iter = testList.iterator();
while (iter.hasNext()) {
t = iter.next();
if (t.equals("a") || t.equals("b")) {
iter.remove();
}
}
System.out.println("使用iterator移除相邻元素a、b后结果:" testList);
}
}
[/java]

您可能感兴趣的文章:
JAVA List使用Remove时的一些问题
解决java.util.ConcurrentModificationException错误办法
java list ArrayList用法详细
在Hibernate的搜索中使用List集合的list-index属性
java中遍历List的几种方法
java中关于Map的几大问题总结
java删除ArrayList中重复的元素
Java学习路径(三)过程篇
java后端如何调python接口
go语言坑之list删除所有元素

[关闭]
~ ~