java list remove 无效_JAVA List使用Remove时的一些问题

本文探讨了在Java中使用List的remove方法移除间隔元素和相邻元素时出现的不同结果。当尝试移除间隔元素如'a'和'c'时,操作成功;但移除相邻元素'a'和'b'时,由于List的remove实现导致了漏删。问题的关键在于List的fastRemove方法,它会将删除元素后的元素前移,如果在循环中按顺序删除相邻元素,会导致漏掉要删除的下一个元素。解决方法包括使用逆序删除或者通过Iterator进行删除,这两种方式都能避免漏删问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 listFactory() {

return new ArrayList(Arrays.asList("a", "b", "c", "d"));

}

public static void main(String[] args) {

List testList = null;

String t;

// 使用iterator移除相邻元素a、b后

testList = listFactory();

Iterator 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]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值