在Java中从ArrayList中删除尾随的零

在Java中从ArrayList中删除尾随的零,java,arraylist,iterator,java-stream,Java,Arraylist,Iterator,Java Stream,对于给定的输入ArrayList,我希望保留非零元素之间的所有前导或0,但希望去掉ArrayList中任何数量的尾随0 输入: 0,11,0,0,0,11,11,0,0,0,0 预期产出: 0,11,0,0,0,11,11 我的解决方案: private List<Integer> foo() { List<Integer> list = Arrays.asList(0, 11, 0, 0, 0, 11, 11, 0, 0, 0);

对于给定的输入ArrayList,我希望保留非零元素之间的所有前导或0,但希望去掉ArrayList中任何数量的尾随0

输入:

0,11,0,0,0,11,11,0,0,0,0

预期产出:

0,11,0,0,0,11,11

我的解决方案:

    private List<Integer> foo() {

        List<Integer> list = Arrays.asList(0, 11, 0, 0, 0, 11, 11, 0, 0, 0);
        Collections.reverse(list);
        Iterator<Integer> iterator = list.iterator();
        int i = 0;
        while (iterator.hasNext() && 0 != iterator.next()) {
            ++i;
        }
        return list.subList(0, i);
    }

我做错了什么?有更好的方法吗?

当然,如果最后一个元素是0,请删除它。重复,直到它不是

e、 g


当然,如果最后一个元素是0,就删除它。重复,直到它不是

e、 g


代码中需要更改三件事

在迭代的情况下,这样做,您希望继续计算零

while (iterator.hasNext() && 0 == iterator.next()) {
倒过来数后面的零

Collections.reverse(list);
将其从0子列表到list.size-i

完整代码

List<Integer> list = Arrays.asList(0, 11, 0, 0, 0, 11, 11, 0, 0, 0);
Collections.reverse(list);
Iterator<Integer> iterator = list.iterator();
int i = 0;
while (iterator.hasNext() && 0 == iterator.next()) {
  ++i;
}
Collections.reverse(list);
return list.subList(0, list.size() - i);

代码中需要更改三件事

在迭代的情况下,这样做,您希望继续计算零

while (iterator.hasNext() && 0 == iterator.next()) {
倒过来数后面的零

Collections.reverse(list);
将其从0子列表到list.size-i

完整代码

List<Integer> list = Arrays.asList(0, 11, 0, 0, 0, 11, 11, 0, 0, 0);
Collections.reverse(list);
Iterator<Integer> iterator = list.iterator();
int i = 0;
while (iterator.hasNext() && 0 == iterator.next()) {
  ++i;
}
Collections.reverse(list);
return list.subList(0, list.size() - i);

@azurefrog的解决方案是最简单的

我们还可以利用类ListIterator一直到最后,并在删除零的同时进行迭代。这几乎是我迄今为止发现的使用previous和hasPrevious的唯一好处:


参见

@azurefrog的解决方案是最简单的

我们还可以利用类ListIterator一直到最后,并在删除零的同时进行迭代。这几乎是我迄今为止发现的使用previous和hasPrevious的唯一好处:

该问题与示例代码相矛盾,因为它提到了一个ArrayList,特别是示例代码中没有ArrayList,并说“摆脱”,这意味着删除项: 您的输入列表通过ArraySList具有固定大小。 您使用的是ListsubList,它不会修改输入列表。 因为您特别询问了ArrayList,所以合理的目标是避免多次代价高昂的调整大小操作。因此,对于这样的问题,在知道如何/是否对列表进行变异后,尝试找到最有效的方法在最后对列表进行变异。 您正在反转输入,但没有反转结果,这意味着结果大部分是反向的。您需要再次调用Collectionsreverse。 倒车是浪费。 一般情况下,避免仅为了修改集合的一部分而更改整个集合(结束),或回答有关集合的问题(尾随的零从何处开始?)?。 因为ArrayList具有快速的随机访问,所以您可以像从头开始一样轻松快速地从末尾向后迭代,因此反向操作没有任何好处。 因为你的问题自相矛盾,这里有两种方法:

在不改变原始列表的情况下:

private List<Integer> foo(ArrayList<Integer> list) {
    int size = list.size();
    int lastNonZero = size - 1;

    // Iterate from the end until we hit a non-zero
    while (lastNonZero >= 0 && list.get(lastNonZero) == 0) {
        lastNonZero--;
    }

    // Truncate if there were trailing zeroes (and at least one non-zero)
    if (lastNonZero < size - 1 && lastNonZero >= 0) {
        list = list.subList(0, lastNonZero);
    }

    // Optional copy for safety:  list = new ArrayList<>(list);

    return list;
 }
突变:

private void foo(ArrayList<Integer> list) {           
    int size = list.size();
    int lastNonZero = size - 1;

    // Iterate from the end until we hit a non-zero
    while (lastNonZero >= 0 && list.get(lastNonZero) == 0) {
        lastNonZero--;
    }

    // Truncate if there were trailing zeroes (and at least one non-zero)
    if (lastNonZero < size - 1 && lastNonZero >= 0) {
        list.subList(lastNonZero + 1, size).clear();
    }
 }
注意:改变列表的最快方法可能是改用ArrayList,但因为它是受保护的,所以需要子类ArrayList来调用它

该问题与示例代码相矛盾,因为它提到了一个ArrayList,特别是示例代码中没有ArrayList,并说“摆脱”,这意味着删除项: 您的输入列表通过ArraySList具有固定大小。 您使用的是ListsubList,它不会修改输入列表。 因为您特别询问了ArrayList,所以合理的目标是避免多次代价高昂的调整大小操作。因此,对于这样的问题,在知道如何/是否对列表进行变异后,尝试找到最有效的方法在最后对列表进行变异。 您正在反转输入,但没有反转结果,这意味着结果大部分是反向的。您需要再次调用Collectionsreverse。 倒车是浪费。 一般情况下,避免仅为了修改集合的一部分而更改整个集合(结束),或回答有关集合的问题(尾随的零从何处开始?)?。 因为ArrayList具有快速的随机访问,所以您可以像从头开始一样轻松快速地从末尾向后迭代,因此反向操作没有任何好处。 因为你的问题自相矛盾,这里有两种方法:

在不改变原始列表的情况下:

private List<Integer> foo(ArrayList<Integer> list) {
    int size = list.size();
    int lastNonZero = size - 1;

    // Iterate from the end until we hit a non-zero
    while (lastNonZero >= 0 && list.get(lastNonZero) == 0) {
        lastNonZero--;
    }

    // Truncate if there were trailing zeroes (and at least one non-zero)
    if (lastNonZero < size - 1 && lastNonZero >= 0) {
        list = list.subList(0, lastNonZero);
    }

    // Optional copy for safety:  list = new ArrayList<>(list);

    return list;
 }
突变:

private void foo(ArrayList<Integer> list) {           
    int size = list.size();
    int lastNonZero = size - 1;

    // Iterate from the end until we hit a non-zero
    while (lastNonZero >= 0 && list.get(lastNonZero) == 0) {
        lastNonZero--;
    }

    // Truncate if there were trailing zeroes (and at least one non-zero)
    if (lastNonZero < size - 1 && lastNonZero >= 0) {
        list.subList(lastNonZero + 1, size).clear();
    }
 }

注意:改变列表的最快方法可能是改用,但由于它受保护,您需要子类ArrayList来调用它。

您的程序是否给出了错误的输出?如果是,请在问题中包括它。您的程序是否给出了错误的输出?如果是这样,请将其包含在问题中。不要像while iterator.hasNext{iterator.next;}那样循环到末尾,只需首先使用list.listIteratorlist.size…这可以与for循环一起使用,即forListIterator i=list.listIteratorlist.size;i、 hasPrevious&&0==i.previous;i、 移除;这几乎和另一个答案一样简单。而且不需要数组。toStringlist.toArray;您只需通过System.out.prin打印即可
tlnlist;,这将产生完全相同的输出。与其像while iterator.hasNext{iterator.next;}那样循环到末尾,只需首先使用list.listIteratorlist.size…这可以与for循环一起使用,即forListIterator i=list.listIteratorlist.size;i、 hasPrevious&&0==i.previous;i、 移除;这几乎和另一个答案一样简单。而且不需要数组。toStringlist.toArray;您只需通过System.out.printlnlist;打印即可;,这将产生完全相同的输出。