问题
在码代码的时候,经常碰到需要删除数组中一些符合指定特征的多个元素,很多人不假思索,对数组进行遍历,然后删除符合特征的元素。
问题是,在删除数组的过程中,数组大小会变化,数组后续元素的下标也会随之变化,从而导致需要被遍历的元素漏掉,甚至数组越界。
如下代码展示这种情况:
//初始化一个数组,元素为 [1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10]
List<Integer> tData = new ArrayList<Integer>();
tData.clear();
for (int i=1;i<=10;i++)
{
tData.add(i);
tData.add(i);
}
System.out.println("--the data before: "+tData);
//删除数组中值为5和10的元素
try {
for (int i=0;i<tData.size();i++)
{
if( tData.get(i)==5||tData.get(i)==10)
{
tData.remove(i);
}
}
}catch (Exception e){
System.out.println("--the data dispose 1 error:"+tData);
}
System.out.println("--the data dispose 1:"+tData);
输出结果为:
--the data before: [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10]
--the data dispose 1:[1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10]
可以发现还有值为5和10的元素没有删除,而遗漏掉。解决方法有多种,下面介绍两种通用
解决方法一:逆向遍历
对数组进行逆向遍历可以有效的解决此问题:逆向遍历,下标不断减小,在删除某个元素后,由于下标同时减小,从而下一个被遍历的元素不会被一遗漏。
仍以上面代码为例,实现方法如下:
System.out.println("--the data before: "+tData);
for (int i=tData.size()-1;i>=0;i--)
{
if(tData.get(i)==5||tData.get(i)==9)
{
tData.remove(i);
}
}
System.out.println("--the data dispose 3:"+tData);
运行结果:
--the data before: [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10]
--the data dispose 2:[1, 1, 2, 2, 3, 3, 4, 4, 6, 6, 7, 7, 8, 8, 10, 10]
解决方法一:删除时下标减一
在对数组进行遍历,删除时,将下标随之进行减小
仍以上面代码为例,实现方法如下:
System.out.println("--the data before: "+tData);
for (int i=0;i<tData.size();i++)
{
if(tData.get(i)==5||tData.get(i)==9)
{
tData.remove(i);
i--;
}
}
System.out.println("--the data dispose 2:"+tData);
运行结果:
--the data before: [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10]
--the data dispose 2:[1, 1, 2, 2, 3, 3, 4, 4, 6, 6, 7, 7, 8, 8, 10, 10]