用arrayList理解这个removeAll java方法

此方法的任务是从arrayList中删除所有出现的值toRemove。 剩下的元素应该只移到列表的开头(大小不会改变)。 最后的所有“额外”元素(但是多次出现的toRemove都在列表中)应该只填充0.该方法没有返回值,如果列表没有元素,它应该没有效果。 不能使用ArrayList类中的remove()removeAll()

方法签名是:

 public static void removeAll(ArrayList list, int toRemove); 

解决方案:

 public static void removeAll(ArrayList list, int toRemove) { for (int i = 0; i < list.size(); i++) { if (list.get(i) = toRemove) { for (int j = i + 1; j < list.size(); j++) { list.set(j - 1, list.get(j)); } list.set(list.size() - 1, 0); i--; } } 

我理解第一个for循环和if语句。 因为人们希望逐个遍历整个arrayList,并且对于每个索引都使用arrayList中存在的数字检查它是否实际上是toRemovee整数。 在这之后我迷路了。

为什么另一个循环? 为什么我们在最后一个之后开始第二个for -loop? 为什么在第二个for循环中我们使用list.set() ,我理解set方法接受两个参数,索引位置和要转到指定位置的元素。 为什么选择j-1 ? 为什么在第二个循环结束后有行: list.set(list.size()-1, 0) ? 为什么我 – ?

有很多活动部件,我想了解逻辑。

谢谢

为什么另一个for -loop? 为什么我们在最后一个之后开始第二个for -loop? 为什么在第二个for循环中我们使用list.set() ,我理解set方法接受两个参数,索引位置和要转到指定位置的元素。 为什么j - 1

该方法完成了文档所说的一切。 内循环将元素左移一个。

 for (int j = i + 1; j < list.size(); j++) { list.set(j - 1, //The index before j (that is, j - 1) is set to... list.get(j)); //the current element. } } 

从找到的索引之后的元素开始,它将左边的那个设置为当前元素。 最终,你最终将所有元素都向左移动。

 list.set(list.size() - 1, 0); 

这将最后一个元素设置为零。 由于您的列表已删除了一个元素,因此您需要删除最后一个元素,因为所有内容都已移位。

例:

在这些示例中, ^是i而*j

 0 1 2 3 4 

说我想删除2。
首先,我会循环直到找到2。

 0 1 2 3 4 ^ index: 2 

现在,我将移动所有内容以删除该元素。 因为我们向左移动,我们需要从i + 1开始(因此for -loop从i + 1

 0 1 3 3 4 ^ * (replaced the one before *) 

接下来,我们再做一次。

 0 1 3 4 4 ^ * 

现在我们完成了。

list.set(list.size() - 1,0);

但是,最后留下4个。 我们需要删除它,因为我们删除了一个元素,并且列表是一个较短的元素。 因此,我们将最后一个元素设置为零以删除它(当然,这假设零不是列表中的有效值)。

注意:

我强烈建议做list.remove(list.size() - 1)而不是调用set 这实际上删除了最后一项,并没有留下“魔数”默认值。

为什么我 - ?

你需要我 - 因为所有东西都向左移动了,所以你需要将索引1更新到左边,即减去一个。 (实际上,你需要做的是在相同的索引处开始迭代,但是因为for -loop每次迭代都会执行i++你需要做到 - “取消”它。)

为什么我们在最后一个之后启动第二个for-loop one?

每次发现出现时,我们都希望将所有以下的arraylist值左移1。

为什么在第二个for循环中我们使用list.set(),我理解set方法接受两个参数,索引位置和要转到指定位置的元素。 为什么j – 1?

j-1用于向左移1。

为什么在第二个循环结束后有行:list.set(list.sise() – 1,0)?

我们向左移动了值,但是最后一个索引(size-1)的值没有被任何东西替换,我们希望它为0

为什么我 – ?

由于当前索引处的值已被另一个值覆盖,我们希望在相同的索引处开始下一次迭代( i--补偿i++ )。

如果你想在FP风格中做同样的事情; 返回一个新的List而不是修改输入,你可以使用Streams。

 public static List removeAll(ArrayList list, int toRemove) { Integer rem = new Integer(toRemove); // OR change toRemove to Integer List ret = list.stream() .filter(i -> !(i.equals(rem))) .collect(Collectors.toList()); return ret; //if you NEED to return ArrayList instead of List //return new ArrayList<>(ret); }