用arrayList理解这个removeAll java方法

时间:2017-01-31 16:14:43

标签: java arraylist

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

方法签名是:

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

解决方案:

public static void removeAll(ArrayList<Integer> 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循环?为什么我们在最后一个之后开始第二个for - 循环? 为什么在第二个for循环中我们使用list.set(),我理解set方法接受两个参数,索引位置和要转到该指定位置的元素。为什么j-1?为什么在第二个循环结束后有一行:list.set(list.size()-1, 0)?为什么i--

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

谢谢

3 个答案:

答案 0 :(得分:3)

  

为什么另一个for - 循环?为什么我们在最后一个之后开始第二个for - 循环?为什么在第二个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 - 循环从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。这实际上删除了最后一项,并且没有留下“幻数”默认值。

  

为什么i--

您需要i--,因为所有内容都向左移动,因此您需要将索引1更新到左侧,即减去一个。 (实际上,你需要做的是在相同的索引开始迭代,但由于for - 循环执行i++每次迭代,你需要做{{1} “取消”它。)

答案 1 :(得分:0)

  

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

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

  

为什么在第二个for循环中我们使用list.set(),我明白了   set方法接受两个参数,索引位置和   元素进入指定位置。为什么j - 1?

j-1用于向左移动。

  

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

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

  

为什么我 - ?

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

答案 2 :(得分:0)

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

public static List<Integer> removeAll(ArrayList<Integer> list, int toRemove) {
    Integer rem = new Integer(toRemove); // OR change toRemove to Integer
    List<Integer> 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);
}