理解这个使用arrayList的removeAll java方法

理解这个使用arrayList的removeAll java方法,java,arraylist,Java,Arraylist,此方法的职责是从arrayList中删除所有出现的值toRemove。剩下的元素应该移到列表的开头(大小不会改变)。末尾的所有“额外”元素(不管列表中出现了多少次toRemove)都应该用0填充。该方法没有返回值,如果列表中没有元素,那么它应该没有任何效果。无法从ArrayList类中使用remove()和removeAll() 方法签名为: public static void removeAll(ArrayList<Integer> list, int toRemove); p

此方法的职责是从arrayList中删除所有出现的值
toRemove
。剩下的元素应该移到列表的开头(大小不会改变)。末尾的所有“额外”元素(不管列表中出现了多少次
toRemove
)都应该用0填充。该方法没有返回值,如果列表中没有元素,那么它应该没有任何效果。无法从ArrayList类中使用
remove()
removeAll()

方法签名为:

public static void removeAll(ArrayList<Integer> list, int toRemove);
publicstaticvoidremoveall(arraylistlist,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--;
        }
    }
publicstaticvoidremoveall(arraylistlist,int-toRemove){
对于(int i=0;i
我很理解第一个
for
循环和
if
语句。因为人们希望逐个遍历整个arrayList,并检查arrayList中是否存在一个数字的每个索引,实际上是
toRemovee
整数。在这一点之后,我就迷路了

为什么另一个
用于
循环?为什么我们在最后一个循环的位置之后开始第二个
用于
循环? 为什么在第二个
for
循环中我们使用
list.set()
,我知道
set
方法包含两个参数,索引位置和要细分到指定位置的元素。为什么
j-1
?为什么在第二个循环结束后有一行:
list.set(list.size()-1,0)
?为什么
i--

有很多运动部件,我想了解其中的逻辑

多谢各位

为什么另一个
for
-循环?为什么我们在最后一个循环之后再开始第二个
for
-循环?为什么在第二个for循环中我们使用
list.set()
,我知道set方法包含两个参数,索引位置和要细分到指定位置的元素。为什么
j-1

该方法执行文档中所述的所有操作。 内部循环将元素向左移动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.
    }
}
这将最后一个元素设置为零。由于列表中删除了一个元素,您需要删除最后一个元素,因为所有元素都已移动

示例:

在这些示例中,
^
是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++
每次迭代,您需要执行
i--
以“取消”把它拿出来。)

为什么我们要在最后一个循环的位置之后开始第二个循环呢

每次发现一个事件时,我们都希望在arraylist的值之后左移1 all

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

j-1
用于向左移动1

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

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

为什么我


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

如果希望以FP样式执行相同操作,请返回新列表而不是修改输入,您可以使用流执行此操作

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);
}
publicstaticlist-removeAll(ArrayList-List,int-toRemove){
Integer rem=新整数(toRemove);//或将toRemove更改为整数
List ret=List.stream()
.filter(i->!(i.equals(rem)))
.collect(Collectors.toList());
返回ret;
//如果需要返回ArrayList而不是List
//返回新的ArrayList(ret);
}

如果(list.get(i)=toRemove)
你是不是想写
=
?实际上,不需要第二个循环。这是一个非常简单的实现。如果你只需要修改传入列表:更改方法以返回void和
list.clear();list.addAll(ret);return ret;
首先,您永远不应该使用
新整数(…)
(在Java 9中,此构造函数已被弃用)。使用自动装箱或显式
整数.valueOf(…)
。但是,不清楚为什么您会假设需要将
int
转换为
整数(/code>。只需使用
。过滤器(i->i>)
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);
}