Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 每个过滤循环的替换内容是什么?_Java_List_Foreach - Fatal编程技术网

Java 每个过滤循环的替换内容是什么?

Java 每个过滤循环的替换内容是什么?,java,list,foreach,Java,List,Foreach,虽然for each循环有很多优点,但问题是,当您想要筛选(筛选意味着从列表中删除元素)列表时,它不起作用,您能不能请任何替换,因为即使遍历索引也不是一个好的选择。您所说的“筛选”是什么意思?从列表中删除某些元素?如果是,您可以使用: for(Iterator it=list.Iterator();it.hasNext();){ MyElement元素=it.next(); 如果(某些条件){ it.remove(); } } 更新(基于评论): 考虑以下示例来说明迭代器是如何工作的。假设我们

虽然for each循环有很多优点,但问题是,当您想要筛选(筛选意味着从列表中删除元素)列表时,它不起作用,您能不能请任何替换,因为即使遍历索引也不是一个好的选择。

您所说的“筛选”是什么意思?从列表中删除某些元素?如果是,您可以使用:

for(Iterator it=list.Iterator();it.hasNext();){
MyElement元素=it.next();
如果(某些条件){
it.remove();
}
}
更新(基于评论):

考虑以下示例来说明迭代器是如何工作的。假设我们有一个包含“a”和“B”的列表:

A B B A

我们想删除所有那些讨厌的
B
s。因此,使用上述循环,代码将按如下方式工作:

  • hasNext()?对next()<代码>元素指向第一个A
  • hasNext()?对next()<代码>元素指向第二个A
  • hasNext()?对next()<代码>元素指向第一个B。删除()。迭代器计数器并没有改变,它仍然指向B所在的位置(从技术上讲,这并不完全正确,但从逻辑上讲,它就是这样工作的)。如果现在再次调用remove(),则会出现异常(因为列表元素不再存在)
  • hasNext()?对next()<代码>元素指向第二个B。其余与#3相同
  • hasNext()?对next()<代码>元素指向第三个A
  • hasNext()?不,我们结束了。列表现在有3个元素

  • Update#2
    remove()
    操作在迭代器上确实是可选的,但这只是因为它在基础集合上是可选的。这里的底线是——如果您的集合支持它(Java集合框架中的所有集合都支持),那么迭代器也会支持它。如果你的收藏不支持它,那你就倒霉了。

    chssly76的答案在这里是正确的——但我很好奇你在“遍历索引不是一个好选择”背后的想法。在许多情况下,尤其是
    ArrayList
    ,它的效率非常高。(事实上,在arraylist的例子中,我相信重复调用
    get(I++)
    比使用迭代器要快一些,尽管这还不足以牺牲可读性)


    广义地说,如果所讨论的对象实现了,那么通过索引访问顺序元素的速度应该与使用迭代器的速度大致相同。如果没有(例如,
    LinkedList
    将是一个很好的反例),那么您是对的;但是不要马上放弃这个选项。

    我已经成功地使用了

    filter(java.util.Collection collection, Predicate predicate) 
    
    commons集合中CollectionUtils的方法


    如果您和我一样,不喜欢在遍历集合的元素时修改集合,或者如果迭代器不提供删除的实现,则可以使用临时集合来只收集要删除的元素。是的,是的,与修改迭代器相比,它的效率更低,但对我来说,更清楚地了解发生了什么:

    List<Object> data = getListFromSomewhere();
    List<Object> filter = new ArrayList<Object>();
    
    // create Filter
    for (Object item: data) {
      if (throwAway(item)) {
        filter.add(item);
      }
    }
    
    // use Filter
    for (Object item:filter) {
      data.remove(item);
    }
    
    filter.clear();
    filter = null;
    
    List data=getListFromSomewhere();
    列表过滤器=新的ArrayList();
    //创建过滤器
    用于(对象项:数据){
    if(一次性(项目)){
    过滤。添加(项目);
    }
    }
    //使用过滤器
    用于(对象项:过滤器){
    数据删除(项目);
    }
    filter.clear();
    filter=null;
    
    @ChssPly76:Thanx作为回复,是的,我的意思是相同的,但是当我删除元素时,它不会影响迭代,因为迭代器来自同一个实例。我想从列表中删除元素(List),我确信在迭代器上调用remove()会影响底层列表。否则就没有意义了,它肯定会从基础列表中删除元素。它不会影响迭代,但是-
    remove()
    在“current”元素上被调用(从上一次
    next()
    方法调用返回的元素),并且它不会更改“current”元素。下一次调用
    Next()
    将从列表中返回以下元素。你能详细说明你的答案吗,这对我来说有些不清楚。请帮助我不幸的是,迭代器#remove()的javadoc有这两个词,大部分都没有被注意到;“可选操作”。甚至没有办法检查是否需要尝试使用哪种方法。remove()根本不可靠,除非您110%确定它能工作,否则不应该使用。是的,但这不会改变事情-如果在这种特定情况下,您的列表是
    ArrayList
    (或类似),那么基于索引的访问将会很快(甚至比使用迭代器快一点),所以这是一个不错的选择。如果这是一个通用的库方法,它可能包含所有类型的列表,而您无法控制这些列表的实现,那么假设它是不好的(尽管您仍然可以检查接口实现)@dtsazza-您在性能方面完全正确(+1)。但是,索引循环的问题是,如果需要从集合中删除某些元素,则很容易将其搞糟。在for循环中修改索引只是一种恶果;虽然循环需要额外的外部计数器,而且感觉不太干净。请在这里详细说明您的答案,这对我和其他人都非常有用这些界面没有通用化,这是我喜欢谷歌收藏的原因
    List<Object> data = getListFromSomewhere();
    List<Object> filter = new ArrayList<Object>();
    
    // create Filter
    for (Object item: data) {
      if (throwAway(item)) {
        filter.add(item);
      }
    }
    
    // use Filter
    for (Object item:filter) {
      data.remove(item);
    }
    
    filter.clear();
    filter = null;