java中的迭代器 - 删除范围内的数字

Posted

技术标签:

【中文标题】java中的迭代器 - 删除范围内的数字【英文标题】:Iterators in java - remove numbers in a range 【发布时间】:2015-03-17 16:39:38 【问题描述】:

我正在尝试使用迭代器从 LinkedList 中删除数字。 我不能让它只从变量之间删除数字。

我的列表包含以下值:1、1、2、0、4、5、6、8、8、3、11、9、12、0、14、0、16]

方法的调用 removeEvenInRange(list,5,13) 应该删除索引 5 和 13 之间的偶数,最后得到一个包含 [1,1,2,0,4,5,3,11,9,0,14,0,16

我不知道如何“告诉”它仅在索引 5 - 13 之间进行迭代。任何有关如何解决此问题的帮助将不胜感激。

这是我目前所拥有的:

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
import java.util.ListIterator;

public class Ex11_3_RemoveEvenInRange 

public static void main(String[] args) 

    List<Integer> list = new LinkedList<>();
    list.addAll(Arrays.asList(1,1,2,0,4,5,6,8,8,3,11,9,12,0,14,0,16));

    removeEvenInRange(list, 5, 13);


private static void removeEvenInRange(List<Integer> list, int i, int j) 


            Iterator<Integer> itr = list.iterator();

            for (int k = i; k < j; k++) 

                int element = itr.next();

                if (element % 2 == 0) 
                    itr.remove();

                
            


                System.out.println(list);

    

【问题讨论】:

如果您可以简单地通过 List API 直接访问元素,为什么还要使用迭代器? for(i=5; i&lt;=13;i++) list.get(i); /* test for even */ 你不明白吗? @Paul 和 Iterator 您无需担心列表大小(通过删除元素会改变),并且可以简单地使用 while(iterator.hasNext()) 循环。 【参考方案1】:

您可以在两个索引之间使用subList。试试吧,

static void removeEvenInRange(List<Integer> list, int i, int j)

    List<Integer> subList= list.subList(i, j);
    Iterator<Integer> itr = subList.iterator();


    while (itr.hasNext())
        int element = itr.next();
        if (element % 2 == 0) 
            itr.remove();
        
    
    System.out.println(list);

【讨论】:

【参考方案2】:

您当前的实现是从索引0 到索引j - i - 1 的列表中删除所有偶数,而不是从ij - 1。范围已移动,因为您直到 k 处于范围内时才进行迭代。

在索引0 处开始您的for 循环,因此您的索引与迭代器的索引一致。然后添加if 语句以确定您的索引k 是否在ij 之间的适当范围内。

for (int k = 0; k < j; k++) 
    int element = itr.next();

    if (k >= i && k < j)
    
        if (element % 2 == 0) 
            itr.remove();
        
    

【讨论】:

if 中不需要 k 【参考方案3】:

如果您想使用迭代器,您可以编写如下内容:

 for (int k = 0; k < j; k++) 

         int element = itr.next();
             if (k>=i) 
                    if (element % 2 == 0) 
                        itr.remove();
                       
                   

          

但是如果你使用get(int index)会更高效

【讨论】:

LinkedList 的情况下不是:get(int index) 是 O(N)。 他可以使用ArrayList实现【参考方案4】:

您需要计数 并推进迭代器,直到到达起始索引。然后,您继续并行计数,通过迭代器迭代和删除要删除的元素,直到 count 达到结束索引。

如果您坚持使用LinkedList,上述过程将比通过List#remove(index) 方法删除更有效(如某些cmets 中所建议的那样),因为每次调用remove 都会通过列表查找索引。

【讨论】:

【参考方案5】:

你不能,除非你在运行你的代码之前调用next()n(在这种情况下是5)次——这太疯狂了。

您最好的选择可能是将您的列表分成三个sublists,遍历中间一个,然后在完成后合并列表。

另一种方法是直接在列表中使用get(index)remove(index),这样可以节省拆分/合并步骤,但您必须确保每次删除都调整索引。拆分/合并方法不易出错。

编辑:@Masud 的答案有示例代码,尽管它缺少合并步骤。

【讨论】:

我不知道为什么迭代到fromIndex 会是疯狂。这肯定比反复调用LinkedList#remove(index) 更有效率。但是使用 sublist 并对其进行迭代是一个好主意,并且可能是最有效的。

以上是关于java中的迭代器 - 删除范围内的数字的主要内容,如果未能解决你的问题,请参考以下文章

vector::erase

迭代器,生成器

Java设计模式之迭代器模式

转到基于范围的 for 循环中的下一个迭代器

Java 迭代器Iterator的详解

迭代器